WindowsのXAMPPのPHPではstrptimeは使用不可。代替はdate_parse_from_formatを使う
2024/08/10
Windowsの PHPには strptimeは未実装。代替は date_parse_from_format
Linuxで動作していたシステムのメンテナンスを行うため、Windowsに XAMPP環境を構築し、そこで動作をさせてみました。
そうしたところ、「strptime()」でエラーが出ました。
エラーメッセージは、以下の通りでした。
Fatal error: Uncaught Error: Call to undefined function strptime() in C:\xampp\htdocs\test.php:999 Stack trace: #0 {main} thrown in C:\xampp\htdocs\test.php on line 999
「『strptime』はないよぅ」という内容です。
ちなみに、「strptime()」は、与えられた文字列が、指定した日時のフォーマットに沿っているか、その日時が存在する日時か、をチェックする関数です。
日時を引数として受け取る祭に、プログラム内で使用する前に正しい日時のフォーマットであることを確認するような場面で使用します。
PHPのマニュアルに Windowsの PHPに strptimeは未実装と書いてある
https://www.php.net/manual/ja/function.strptime.php
PHPの標準的なコマンドだと思っていましたが、いろいろ調べてみた結果、マニュアルにしっかりと書かれていました。
1 |
注意: この関数は Windows 環境にはまだ実装されていません。 |
改めて、手元にある XAMPP環境で確認したところ、下記のいずれにも入っていませんでしたので、バージョンの問題でもないようです。
PHP5.6.24
PHP7.3.2
PHP8.1.4
https://www.php.net/manual/ja/function.strptime.php
また、上記のマニュアルの最初の方に下記のように書いてあります。
1 |
警告:この関数は PHP 8.1.0 で 非推奨になります。この関数に頼らないことを強く推奨します。 |
つまりは、「まだ実装されていません」の「まだ」は、「まだ」と言いつつ、非推奨になることを期待して放置したのではないか、と疑問に感じるところです。
「strptime()」と「date_parse_from_format()」の違いと実装方法
それはさておき、Windows環境の XAMPPでは「strptime()」は使えませんので、代替の関数として用意されている「date_parse_from_format()」を使うとよさそうです。
https://www.php.net/manual/ja/function.date-parse-from-format.php
ただ、「strptime()」と「date_parse_from_format()」とでは少し挙動が異なりますので、単純に「strptime」を「date_parse_from_format」に置き換えるだけ、というわけにはいかないようです。
では、詳しく確認していきましょう。
「strptime()」と「date_parse_from_format()」の違い:実装の方法
「strptime()」と「date_parse_from_format()」を使用して、年月日が正しいかどうかをチェックする処理を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php $datetime = '2024-08-03'; echo "<br>■strptime<br><pre>"; var_export(strptime($datetime, '%Y-%m-%d')); echo "</pre>"; if(strptime($datetime, '%Y-%m-%d')){ echo "true:strptime"; } else { echo "false:strptime"; } echo " <br>"; echo "<br>■date_parse_from_format<br><pre>"; var_export(date_parse_from_format('Y-m-d', $datetime)); echo "</pre>"; if(date_parse_from_format('Y-m-d', $datetime)){ echo "true:date_parse_from_format"; } else { echo "false:date_parse_from_format"; } |
「strptime()」と「date_parse_from_format()」の違い・引数の順番が違う
実装方法の 1つめの違いは、「strptime()」と「date_parse_from_format()」とで引数の、チェックする対象の変数と、日時のフォーマットの順番が逆になっています。
チェック対象の変数が、「strptime()」は第一引数なのに対し、「date_parse_from_format()」は第二引数になっています。
「strptime()」と「date_parse_from_format()」の違い・日時のフォーマットの指定形式が違う
実装方法の 2つ目の違いは、日時をチェックするためのフォーマットの指定形式が異なります。
「2024-08-03
」をチェックするにあたって、「strptime()」では「%Y-%m-%d
」と指定しますが、「date_parse_from_format()」では「Y-m-d
」となります。
各項目のフォーマットに関しては、下記の PHPのマニュアルを参照してください。
PHPマニュアル DateTimeImmutable::createFromFormat
https://www.php.net/manual/ja/datetimeimmutable.createfromformat.php
「strptime()」と「date_parse_from_format()」の違い:実行結果
「strptime()」と「date_parse_from_format()」とでは、実装方法も異なりますが、実行結果(レスポンス)も異なります。
前項のサンプルプログラムを実行した結果が下記になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
■strptime array ( 'tm_sec' => 0, 'tm_min' => 0, 'tm_hour' => 0, 'tm_mday' => 3, 'tm_mon' => 7, 'tm_year' => 124, 'tm_wday' => 6, 'tm_yday' => 215, 'unparsed' => '', ) true:strptime ■date_parse_from_format array ( 'year' => 2024, 'month' => 8, 'day' => 3, 'hour' => false, 'minute' => false, 'second' => false, 'fraction' => false, 'warning_count' => 0, 'warnings' => array ( ), 'error_count' => 0, 'errors' => array ( ), 'is_localtime' => false, ) true:date_parse_from_format |
年、月、日などの値が入っている配列のキー名称も異なりますが、値がない場合の結果の表記も異なります。
「strptime()」と「date_parse_from_format()」の違い・正しくない日時のレスポンスが全く違う
正しくない「2024-08-33
」を日時として与えた場合
前項では、正しい年月日が入力された場合の処理ですが、ここでは、正しくない「2024-08-33
」を日時として与えた場合の確認をしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$datetime = '2024-08-33'; echo "<br>■strptime<br><pre>"; var_export(strptime($datetime, '%Y-%m-%d')); echo "</pre>"; if(strptime($datetime, '%Y-%m-%d')){ echo "true:strptime"; } else { echo "false:strptime"; } echo " <br>"; echo "■date_parse_from_format<br><pre>"; var_export(date_parse_from_format('Y-m-d', $datetime)); echo "</pre>"; if(date_parse_from_format('Y-m-d', $datetime)){ echo "true:date_parse_from_format"; } else { echo "false:date_parse_from_format"; } |
以下が、上記の結果となります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
■strptime false false:strptime ■date_parse_from_format array ( 'year' => 2024, 'month' => 8, 'day' => 33, 'hour' => false, 'minute' => false, 'second' => false, 'fraction' => false, 'warning_count' => 1, 'warnings' => array ( 10 => 'The parsed date was invalid', ), 'error_count' => 0, 'errors' => array ( ), 'is_localtime' => false, ) true:date_parse_from_format |
上記を確認すると明らかな違いがあります。
「strptime()」では「false」を返して終了です。
ですが、「date_parse_from_format()」は情報を返してくれます。
また、「'warning_count' => 1
」「'warnings' => array(10 => 'The parsed date was invalid',)
」のように、不具合がある内容を返してくれます。
正しくない「2024-a-03
」を日時として与えた場合
次に、「2024-a-03
」を入力した場合の結果を確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
array ( 'year' => 2024, 'month' => 3, 'day' => false, 'hour' => false, 'minute' => false, 'second' => false, 'fraction' => false, 'warning_count' => 0, 'warnings' => array ( ), 'error_count' => 2, 'errors' => array ( 5 => 'Unexpected data found.', 9 => 'Not enough data available to satisfy format', ), 'is_localtime' => false, ) |
「月」に「a」を入れていますので「'error_count' => 2
」となり、エラー内容が返ってきています。
ちなみに「2024-08-33
」の時のワーニングメッセージは「The parsed date was invalid」で「date」ですが、「2024-a-03
」のエラーメッセージは「Unexpected data found.」で「data」ですね。
「2024-08-33
」は日時として認識できますが、「2024-a-03
」は日時としては認識できません、ということかも知れないですね。
「strptime()」と「date_parse_from_format()」を使った日時チェックの記述方法
これまでの確認した内容から、「strptime()」と「date_parse_from_format()」を使用して、日付のフォーマットが正しいか否かをチェックする処理はそれぞれ下記のようになります。
1 2 3 4 5 6 |
// strptime を使用する場合 if(strptime($datetime, '%Y-%m-%d')){ // 正しい時の処理 } else { // 正しくない時の処理 } |
1 2 3 4 5 6 7 |
// date_parse_from_format を使用する場合 $dateParseFromFormat = date_parse_from_format('Y-m-d', $datetime); if(!$dateParseFromFormat["warning_count"] && !$dateParseFromFormat["error_count"]){ // 正しい時の処理 } else { // 正しくない時の処理 } |
「date_parse_from_format()」を使用する場合は、ワーニングとエラーの数が「0」である場合に「正しい」と判断する処理になりますね。
日時のフォーマットが正しくない場合「strptime()」では「false」になりますが、「date_parse_from_format()」ではフォーマットが正しい、正しくないに関わらずレスポンスはありますので、「date_parse_from_format()」では、レスポンスの有無で判定はできないということになります。
「strptime()」は環境によって挙動が異なる
「strptime()」についてさらなる追い討ちが!
https://www.php.net/manual/ja/function.strptime.php
「strptime()」については、マニュアルに下記のようにも書かれています。
1 |
注意:内部では、この関数はシステムの C ライブラリ関数 strptime() をコールしています。 このライブラリ関数は、OS によって挙動が異なることがあります。 |
https://qiita.com/YujiSoftware/items/1b65591efda79933fc79
上記の記事では挙動の違いを実際に試した結果を紹介してあります。
つまりは、「strptime()」は Linuxと Macで挙動が異なり、Windowsには実装されていない...ということになるわけです。
そんな関数は安心して使えないので、PHP8.1での非推奨勧告と関係なく、「date_parse_from_format()」を使う方がいいんでしょうね。
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
Smartyの Syntax Errorの原因はスペースかも
Smartyのなかなか原因がつかめない Syntax Errorの原因はスペースかもしれません。
-
cURLを利用する際の注意点「
&
」があるURLは「”
」で囲むcURLでURLはダブルクォーテーションで囲む。LinuxでもWindowsでもコマンドでは「&」は意味を持つ文字のためエラー原因になる。クォーテーションは常につけておく方が無難。
-
指定した数で文字列を丸める(n文字目で…にする)関数substr、mb_substr、mb_strimwidthの違い
文字列を指定された数で抜き出すPHPの関数、substr、mb_substr、mb_strimwidthについての解説。似た関数だが引数の指定方法が違ったり、文字数がバイト数か文字数かも違ったり、注意が必要だ。
-
include、requireのパス指定をdirname(__FILE__)、__DIR__と書く理由
include、requireのパスの指定を dirname(__FILE__)、__DIR__で記述する理由に付いて解説。相対パス、絶対パスを直書き、パスを書かない場合は何が問題かを説明。
-
PHPで正規表現の検証には preg_match_allが便利
PHPで正規表現の検証には preg_match_allが便利です。その便利さの使い方の解説です。
-
PHPのスクレイピングライブラリ「PHP Simple HTML DOM Parser」の使い方
PHPのスクレイピングライブラリ「PHP Simple HTML DOM Parser」の使い方を解説。要素を取得する方法、そこから属性を取得する方法を解説。また、マニュアルにはない注意点なども解説。
-
Phpmailerでスパム回避!Gmail等のSMTPを経由するPHPのメールフォーム解説
お問い合わせ等のメールフォームから送ったメールがスパム扱いされる!その対策としてライブラリ「Phpmailer」を使う方法を解説。関数化していますのでコピペでOK。
-
PHPで配列の値をダブルクオーテーションで囲んでimplodeでカンマ区切りにする方法
PHPで配列の値を、preg_replace関数でクォーテーションで囲み、implode関数で「,(カンマ)」で区切ってテキスト化する方法。この方法であれば配列が空でも分岐の処理は必要なし!
-
配列の値をテキスト表示する際に「、」でつなげるときの処理方法の一例
配列の値を「、」でつないで出力する際、単純にforeachで繰り返し処理をすると「イヌ、サル、キジ、」となるが文字列最後の「、」を出力しない方法を3つ解説している。
-
乱数発生器(パスワード生成サービス)がバージョンアップで高速化!
乱数やパスワードを生成する乱数発生器を高速化!重複しない10桁、20桁の文字列を10万件、20万件と生成することも可能!イベントのキャンペーンのシリアルコードなどにも利用可能!