エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


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の標準的なコマンドだと思っていましたが、いろいろ調べてみた結果、マニュアルにしっかりと書かれていました。
 

注意: この関数は Windows 環境にはまだ実装されていません。

 
 
改めて、手元にある XAMPP環境で確認したところ、下記のいずれにも入っていませんでしたので、バージョンの問題でもないようです。
 PHP5.6.24
 PHP7.3.2
 PHP8.1.4
 
 
https://www.php.net/manual/ja/function.strptime.php
また、上記のマニュアルの最初の方に下記のように書いてあります。
 

警告:この関数は 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()」を使用して、年月日が正しいかどうかをチェックする処理を行います。
 

<?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()」とでは、実装方法も異なりますが、実行結果(レスポンス)も異なります。
 
前項のサンプルプログラムを実行した結果が下記になります。
 

■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」を日時として与えた場合の確認をしてみます。
 

$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";
}

 
 
以下が、上記の結果となります。
 

■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」を入力した場合の結果を確認します。
 

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()」を使用して、日付のフォーマットが正しいか否かをチェックする処理はそれぞれ下記のようになります。
 

// strptime を使用する場合
if(strptime($datetime, '%Y-%m-%d')){
//  正しい時の処理
} else {
//  正しくない時の処理
}

 

// 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()」については、マニュアルに下記のようにも書かれています。
 

注意:内部では、この関数はシステムの C ライブラリ関数 strptime() をコールしています。 このライブラリ関数は、OS によって挙動が異なることがあります。

 
https://qiita.com/YujiSoftware/items/1b65591efda79933fc79
上記の記事では挙動の違いを実際に試した結果を紹介してあります。
つまりは、「strptime()」は Linuxと Macで挙動が異なり、Windowsには実装されていない...ということになるわけです。
 
そんな関数は安心して使えないので、PHP8.1での非推奨勧告と関係なく、「date_parse_from_format()」を使う方がいいんでしょうね。

 - PHP・Smarty・ECCUBE

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

乱数発生器(パスワード生成サービス)がバージョンアップで高速化!
乱数発生器(パスワード生成サービス)がバージョンアップで高速化!

乱数やパスワードを生成する乱数発生器を高速化!重複しない10桁、20桁の文字列を10万件、20万件と生成することも可能!イベントのキャンペーンのシリアルコードなどにも利用可能!

ECCUBEでアップロードできない。upload_max_filesizeを設定する場所

テンプレートをアップロードする際に発生するエラー「テンプレートファイルがアップロードされていません」の対処方法。これはファイル容量の制限に引っかかっています。

複数銘柄を指定して株価チャートを一覧するツール公開

入力銘柄の5日間、3か月間、6か月間、1年間、2年間の株価チャートを一覧表示しますのでチャートで売買判断をするのに最適です。

PHPで APIにアクセスする際などに使用する cURLのサンプルプログラム
PHPで APIにアクセスする際などに使用する cURLのサンプルプログラム

PHPのcURLを使用して各種APIにアクセスするサンプルプログラムを作成し、その処理を解説。カオナビAPIのみならず、他の多くのAPIにアクセスする際にも使用できる。

ECCUBEでテンプレートファイルのファイルサイズは10MB以下のものを使用してくださいのエラーが出た場合

テンプレートをアップロードする際にファイルサイズが大きすぎてエラーが表示される際の対処方法解説。パラメータ設定で設定する制限について解説を行っています。

ob_start、ob_get_contents関数でPHPの標準出力をバッファリング・変数に代入

標準出力をバッファリングし変数に代入することができるob_start()関数の解説。include()の処理をバッファリングすることで自由な場所に処理を記述することが可能。

PHP画面が真っ白 header(“Location: $url”);

PHPの開発で header(“Location: $url”);を使うと画面が真っ白になる不具合が出る場合もあります。

Smartyのテンプレート内の処理で計算、加工をする方法

Smartyのテンプレート上で変数を計算する、加工する方法を解説します。

Smartyの Syntax Errorの原因はスペースかも

Smartyのなかなか原因がつかめない Syntax Errorの原因はスペースかもしれません。

PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う
PHPで1ヵ月前、先月、今月1日、来月末の日付などの算出はDateTimeImmutableを使う

PHPには日時をオブジェクトとして生成する関数「DateTimeImmutable」「DateTime」が用意されている。これを利用して1ヶ月後、月初日、月末日、5日後などを指定して日付を取得できる。