#author("2023-11-03T01:56:00+00:00","","") #author("2023-11-03T02:07:37+00:00","","") [[PHPめも]] PHPで作成したWEBアプリで未来や過去の日時に変更して動作確認したいことは結構あります。~ いくつかやり方はあります。 #contents *dateコマンドを使う [#se277347] よく使われるのはdateコマンドでサーバの時間を変更してしまうことでしょう。~ ただ他のWEBアプリに影響が出たり、PHP-FPMのキャッシュが更新されなかったりと何かと悪影響が出るのでおすすめしないです。 現在日時を確認 # date Fri Nov 3 01:24:56 UTC 2023 2023年11月4日12時に変更 # date --set "2023/11/04 12:00:00" Sat Nov 4 12:00:00 UTC 2023 確認 # date Sat Nov 4 12:00:03 UTC 2023 戻す # ntpdate -s -b ntp.jst.mfeed.ad.jp Docker環境で operation not permitted のエラーが出る場合は docker-compose.yml へ設定を追加します。 services: app: # これを追加 privileged: true ntpdate が無い場合は入れます。 # apt install ntpdate *Carbonを使う [#sbaa587d] setTestNow が使えます。~ ただ使えるようにあらかじめ書いておかないといけないです。 $knownDate = Carbon::create(2001, 5, 21, 12); // create testing date Carbon::setTestNow($knownDate); // set the mock (of course this could be a real mock object) echo Carbon::getTestNow(); // 2001-05-21 12:00:00 echo Carbon::now(); // 2001-05-21 12:00:00 echo new Carbon(); // 2001-05-21 12:00:00 echo Carbon::parse(); // 2001-05-21 12:00:00 echo new Carbon('now'); // 2001-05-21 12:00:00 echo Carbon::parse('now'); // 2001-05-21 12:00:00 echo Carbon::create(2001, 4, 21, 12)->diffForHumans(); // 1 month ago var_dump(Carbon::hasTestNow()); // bool(true) Carbon::setTestNow(); // clear the mock var_dump(Carbon::hasTestNow()); // bool(false) echo Carbon::now(); // 2023-10-03 07:59:07 // Instead of mock and clear mock, you also can use withTestNow(): Carbon::withTestNow('2010-09-15', static function () { echo Carbon::now(); }); // 2010-09-15 00:00:00 https://carbon.nesbot.com/docs/#api-testing *Chronosを使う [#x582db0a] Carbonと同様に setTestNow が使えます。~ ただ使えるようにあらかじめ書いておかないといけないです。 Chronos::setTestNow(new Chronos('1975-12-25 00:00:00')); $time = new Chronos(); // 1975-12-25 00:00:00 $time = new Chronos('1 hour ago'); // 1975-12-24 23:00:00 https://book.cakephp.org/chronos/2/ja/index.html#id11 *php-timecopを使う [#ub9df89e] PHPの拡張モジュールを入れる方法です。~ 個人的におすすめ。 PECLが用意されていますが、PHP7.2までしか対応していません。~ https://pecl.php.net/package/timecop Gitもありますが、同様メンテナンスが止まっています。~ https://github.com/hnw/php-timecop さらに調べると本家からforkして2023年11月時点でPHP8.2まで対応しているのでこれを使います。~ https://github.com/kiddivouchers/php-timecop **インストールから使用方法まで [#z579fcaf] **インストール [#g4168f1e] # cd /usr/local/src/ # git clone https://github.com/kiddivouchers/php-timecop.git # cd php-timecop # phpize # ./configure # make # make install # vi /usr/local/etc/php/php.ini extension=timecop.so WEBサーバを再起動して timecop が含まれているか確認します。 # php -m **使用方法 [#m41c3535] 使える関数は3つです。 if (function_exists('timecop_freeze')) { $unixtimestamp = (new \DateTime('2023-11-04 12:00:00'))->format('U'); // 日時を固定 timecop_freeze($unixtimestamp); echo (new \DateTime())->format('Y-m-d H:i:s').'<br>'; echo date('Y-m-d H:i:s').'<br>'; // 日時へ変更 timecop_travel($unixtimestamp); echo (new \DateTime())->format('Y-m-d H:i:s').'<br>'; echo date('Y-m-d H:i:s').'<br>'; sleep(10); echo (new \DateTime())->format('Y-m-d H:i:s').'<br>'; echo date('Y-m-d H:i:s').'<br>'; // 日時を戻す timecop_return(); } 結果 2023-11-04 12:00:00 2023-11-04 12:00:00 2023-11-04 12:00:00 2023-11-04 12:00:00 2023-11-04 12:00:10 2023-11-04 12:00:10