確認スクリプト
test.php
<?php
$format = 'Y-m-d H:i:s';
foreach(['Asia/Tokyo', 'Etc/GMT-9'] as $timezone) {
date_default_timezone_set($timezone);
echo "$timezone\n";
$datetime = new DateTimeImmutable();
echo " / timestamp / date / DateTimeImmutable\n";
for($i = 0; $i < 10; $i++) {
$timestamp = -2587712405 + $i;
printf("%4d / %d / %s / %s\n",
$i,
$timestamp,
date($format, $timestamp),
$datetime->setTimestamp($timestamp)->format($format)
);
}
echo "\n";
}
foreach(['Asia/Tokyo', 'Etc/GMT-9'] as $timezone) {
date_default_timezone_set($timezone);
echo "$timezone\n";
echo strtotime('1887-12-31 23:59:59')."\n";
echo strtotime('1888-01-01 00:00:00')."\n\n";
}
$ php -v
PHP 7.4.4 (cli) (built: Mar 20 2020 13:47:45) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.4, Copyright (c), by Zend Technologies
$ php test.php
Asia/Tokyo
/ timestamp / date / DateTimeImmutable
0 / -2587712405 / 1888-01-01 00:18:54 / 1888-01-01 00:18:54
1 / -2587712404 / 1888-01-01 00:18:55 / 1888-01-01 00:18:55
2 / -2587712403 / 1888-01-01 00:18:56 / 1888-01-01 00:18:56
3 / -2587712402 / 1888-01-01 00:18:57 / 1888-01-01 00:18:57
4 / -2587712401 / 1888-01-01 00:18:58 / 1888-01-01 00:18:58
5 / -2587712400 / 1888-01-01 00:00:00 / 1888-01-01 00:00:00
6 / -2587712399 / 1888-01-01 00:00:01 / 1888-01-01 00:00:01
7 / -2587712398 / 1888-01-01 00:00:02 / 1888-01-01 00:00:02
8 / -2587712397 / 1888-01-01 00:00:03 / 1888-01-01 00:00:03
9 / -2587712396 / 1888-01-01 00:00:04 / 1888-01-01 00:00:04
Etc/GMT-9
/ timestamp / date / DateTimeImmutable
0 / -2587712405 / 1887-12-31 23:59:55 / 1887-12-31 23:59:55
1 / -2587712404 / 1887-12-31 23:59:56 / 1887-12-31 23:59:56
2 / -2587712403 / 1887-12-31 23:59:57 / 1887-12-31 23:59:57
3 / -2587712402 / 1887-12-31 23:59:58 / 1887-12-31 23:59:58
4 / -2587712401 / 1887-12-31 23:59:59 / 1887-12-31 23:59:59
5 / -2587712400 / 1888-01-01 00:00:00 / 1888-01-01 00:00:00
6 / -2587712399 / 1888-01-01 00:00:01 / 1888-01-01 00:00:01
7 / -2587712398 / 1888-01-01 00:00:02 / 1888-01-01 00:00:02
8 / -2587712397 / 1888-01-01 00:00:03 / 1888-01-01 00:00:03
9 / -2587712396 / 1888-01-01 00:00:04 / 1888-01-01 00:00:04
Asia/Tokyo
-2587713540
-2587712400
Etc/GMT-9
-2587712401
-2587712400
タイムゾーンをEtc/GMT-9にすると大丈夫っぽい。
他のタイムゾーンは未確認。
JavaScriptはどうなのか確認してみたら、同様のずれ。
(Chrome 83で確認)
{
for(let i = 0; i < 10; i++) {
const timestamp = -2587712405 + i;
console.log(timestamp * 1000, new Date(timestamp * 1000));
}
}
-2587712405000 Sun Jan 01 1888 00:18:54 GMT+0918 (日本標準時)
-2587712404000 Sun Jan 01 1888 00:18:55 GMT+0918 (日本標準時)
-2587712403000 Sun Jan 01 1888 00:18:56 GMT+0918 (日本標準時)
-2587712402000 Sun Jan 01 1888 00:18:57 GMT+0918 (日本標準時)
-2587712401000 Sun Jan 01 1888 00:18:58 GMT+0918 (日本標準時)
-2587712400000 Sun Jan 01 1888 00:00:00 GMT+0900 (日本標準時)
-2587712399000 Sun Jan 01 1888 00:00:01 GMT+0900 (日本標準時)
-2587712398000 Sun Jan 01 1888 00:00:02 GMT+0900 (日本標準時)
-2587712397000 Sun Jan 01 1888 00:00:03 GMT+0900 (日本標準時)
-2587712396000 Sun Jan 01 1888 00:00:04 GMT+0900 (日本標準時)