LoginSignup
4
2

More than 3 years have passed since last update.

PHP タイムゾーンがAsia/Tokyoの場合、1888-01-01より前のdateの結果がおかしい

Posted at

確認スクリプト

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 (日本標準時)
4
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2