- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2023-11-03T00:25:59+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
**インストール [#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