Моя проблема с этим кодом
$d1 = new DateTime('2016-02-29', new DateTimeZone('UTC'));
$d2 = new DateTime('1998-03-01', new DateTimeZone('UTC'));
echo $d1->diff($d2)->y;
Не могли бы вы так любезно выполнить эту команду на своем компьютере?
php -r "\$d1 = new DateTime('2016-02-29', new DateTimeZone('UTC'));\$d2 = new DateTime('1998-03-01', new DateTimeZone('UTC')); echo \$d1->diff(\$d2)->y;"
Это возвращает 18
в моей машине, но прошло уже 17 лет, а не 18.
Я не могу понять, почему, и в этом PHP переводчик онлайн
http://sandbox.onlinephpfunctions.com/code/50cc70c56695f08c62047fb7841aae9fec4c2ec6
Это говорит 17
!
Мой php.ini имеет
php -i | grep timezone
Default timezone => Europe/Madrid
date.timezone => Europe/Madrid => Europe/Madrid
Но если я перехожу на «UTC», он продолжает терпеть неудачу и говорит 18 лет
Также это не имеет значения, так как я устанавливаю часовой пояс UTC в коде, чтобы избежать перехода на летнее время.
В чем дело?!
РЕДАКТИРОВАТЬ:
php -r "\$d1 = new DateTime('2016-02-29T00:00:00Z');\$d2 = new DateTime('1998-03-01T00:00:00Z'); echo \$d1->diff(\$d2)->y;"
Это дает мне 17
Кажется, что DateTime думает, что входные данные поступают как часовой пояс не в формате UTC, и это делает странные внутренние вещи оттуда.
Обе даты представляют один и тот же — 59-й — день года:
$ php -a
Interactive mode enabled
php > var_dump(DateTime::createFromFormat('d.m.Y', '01.03.1998')->format('z'));
string(2) "59"php > var_dump(DateTime::createFromFormat('d.m.Y', '29.02.2016')->format('z'));
string(2) "59"
Не сказать, что вы не правы, но также совершенно справедливо сказать, что прошло 18 лет между 59-м днем 1998 года и 59-м днем 2016 года.
Если бы мне пришлось угадывать, PHP вычисляет разницу именно таким образом в этом конкретном сценарии, и это, очевидно, крайний случай, поэтому мы просто должны принять парадокс.
Других решений пока нет …