この前ハマったので。
結論を先に言うと、new DateTimeImmutable($time, $timezone);
では$timezone
よりも、文字列の$time
のタイムゾーンを優先して判定するということらしいです。
想定通りに動作したケース
new_jst_datetime_immutable.php
<?php
/**
* JSTのDateitmeImmutableを返却する
*
* @param string $time
* @return DateTimeImmutable
* @throws Exception
*/
function new_jst_datetime_immutable(string $time)
{
$timezone_jst = new DateTimeZone('Asia/Tokyo');
return new DateTimeImmutable($time, $timezone_jst);
}
without_timezone.php
<?php
require_once('new_jst_datetime_immutable.php');
// timezoneが付いていない文字列
$datetime_utc = new DateTimeImmutable('2020-12-30T12:00:00');
$datetime_jst = new_jst_datetime_immutable('2020-12-30T12:00:00');
var_dump($datetime_utc);
var_dump($datetime_jst);
$ php without_timezone.php
object(DateTimeImmutable)#1 (3) {
["date"]=>
string(26) "2020-12-30 12:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
object(DateTimeImmutable)#3 (3) {
["date"]=>
string(26) "2020-12-30 12:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(10) "Asia/Tokyo"
}
想定通りに動作しないケース
with_timezone.php
<?php
require_once('new_jst_datetime_immutable.php');
// timezone付きの文字列
$datetime_utc = new DateTimeImmutable('2020-12-30T12:00:00+0000');
$datetime_jst = new_jst_datetime_immutable('2020-12-30T12:00:00+0000');
var_dump($datetime_utc);
var_dump($datetime_jst);
$ php with_timezone.php
object(DateTimeImmutable)#1 (3) {
["date"]=>
string(26) "2020-12-30 12:00:00.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
object(DateTimeImmutable)#3 (3) {
["date"]=>
string(26) "2020-12-30 12:00:00.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
$datetime_jst
のtimezone
がAsia/Tokyo
でなく+00:00
となっています。
動作確認用
% php -v
PHP 7.3.24-(to be removed in future macOS) (cli) (built: Nov 23 2020 06:45:16) ( NTS )