エス技研

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.

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

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

  関連記事

cURLを利用する際の注意点「&」があるURLは「"」で囲む
cURLを利用する際の注意点「&」があるURLは「”」で囲む

cURLでURLはダブルクォーテーションで囲む。LinuxでもWindowsでもコマンドでは「&」は意味を持つ文字のためエラー原因になる。クォーテーションは常につけておく方が無難。

ECCUBEの注文完了画面注文番号と商品情報を編集するCRITEO(クリテオ)タグを編集

ECCUBEの注文完了画面にクリテオのタグを編集する方法を紹介。標準機能では完了画面に注文IDや購入商品の情報を渡さないため改修が必要です。

Phpmailerでスパム回避!Gmail等のSMTPを経由するPHPのメールフォーム解説

お問い合わせ等のメールフォームから送ったメールがスパム扱いされる!その対策としてライブラリ「Phpmailer」を使う方法を解説。関数化していますのでコピペでOK。

パーミッション(属性)一括変更ツール・WordPress最適化済

WordPressのパーミッション(属性)を一括変更するツールを作成!ファイル、フォルダのパーミッションが一覧表示でき、ファイルを選んでパーミッションの変更が行えます。

ECCUBEでカード決済NGの受注情報をマイページ購入履歴に表示しない方法解説

ECCUBEでカード決済に失敗しても購入履歴一覧に注文情報(受注情報)が表示される問題への対処方法を解説。受注情報レコードの作成の流れとステイタスについても解説。

sleepの秒指定は整数のみなので1.5秒はsleep、usleepを組み合わせる
sleepの秒指定は整数のみなので1.5秒はsleep、usleepを組み合わせる

PHPのプログラム処理を遅延させる「sleep()」は整数秒単位。「usleep()」は1秒未満のマイクロ秒単位。では「1.5」秒はどう表現するのか。「sleep()」「usleep()」を組み合わせる。その解説。

GMOペイメントゲートウェイのjava.io.IOExceptionのエラー

ECCUBEの決済でGMOペイメントゲートウェイのモジュールを使ってテスト決済を行った場合の不具合、java.io.IOExceptionと言うエラーの原因と対策方法の解説です。

ECCUBEを開発環境から本番ドメインに変更でエラーが・パス変更について

レンタルサーバでサーバ会社から割り当てられたURLで開発し、本番公開時にドメインを当てたらエラーが!そんな場合の対処方法の解説。対処方法は簡単ですが管理画面からは対応不可。

路線・駅検索のために緯度経度からPHPで簡易的に距離を計算する処理解説
路線・駅検索のために緯度経度からPHPで2点間の距離を計算する処理解説

路線・駅検索の仕組みの構築は大変。それを簡易に実装するために緯度経度を元に距離計算をする仕組みを考案。まずは2点間の距離を計算する仕組みを解説し、距離計算にまつわる関連技術も紹介。

ECCUBEの商品一覧ページのSEO対策!rel=”next” rel=”prev”を設定

Googleは関連あるページはその旨明示するよう求めています。ECCUBEの商品一覧ページでその求めに応じるための「rel=”next”」「rel=”prev”」について解説します。