Подтвердить что ты не робот

Как вы объясните результат для нового \DateTime ('0000-00-00 00:00:00')?

Вот тестовый код:

<?php

ini_set('date.timezone', 'Europe/London');    
$dt = new \DateTime('0000-00-00 00:00:00');

var_dump($dt);

Это обеспечивает:

object(DateTime)[1]
  public 'date' => string '-0001-11-30 00:00:00' (length=20)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/London' (length=13)

Если это не действительная дата. Я не понимаю возвращаемое значение, особенно месяц... Можете ли вы объяснить?

4b9b3361

Ответ 1

Здесь вы видите два эффекта. Первый заключается в том, что вы используете способ записи для даты, которая может быть записана в нескольких формах:

0000-01-01 same as  0000-01-01
0000-01-00 same as -0001-12-31
0000-00-01 same as -0001-12-01
0000-00-00 same as -0001-11-30

Итак, по самой дате вы уже указываете 30-е ноября -1.

Теперь есть смещение по времени, которое отличается от 9 минут и 21 секунды. Это связано с изменением часов по сравнению с UTC в Париже/Франции, которое произошло 10 марта 1911 года 23: 51: 38/39 локального времени.


Я немного изменил ваш пример кода и представил настройки Европы/Парижа, как у вас есть, что играет определенную роль. Этот код также сообщает смещение в секундах от UTC (Z), которое вы ищете:

$dt = new DateTime('0000-00-00 00:00:00', new DateTimeZone('Europe/Paris'));
printf("%s secs offset from UTC\n", $dt->format('r T (e) Z'));

Я немного изменил даты

Fri, 10 Mar 1911 23:51:38 +0009 PMT (Europe/Paris) 561 secs offset from UTC
                                                   ^^^

Через секунду:

Fri, 10 Mar 1911 23:51:39 +0000 WET (Europe/Paris) 0 secs offset from UTC

Когда местное стандартное время собиралось достичь Суббота, 11 марта 1911 года, 00:01:00 часы были повернуты назад 0:09:21 часов до Пятница, 10 марта 1911 года, 23:51:39 вместо этого местное стандартное время.

Это 561 сек. Ссылка: Изменения часов в Париже - даты смены времени в 1911 году и Изменение часовых поясов и даты начала и окончания летнего времени между 1900 и 1924 годами.

Ответ 2

Похоже, обработка ошибок в DateTime является неполной. Обычно другие функции PHP обрабатывают "0000-00-00" как ошибку (неверная дата).

DateTime должен следовать тем же рекомендациям, но это не так. Этот код не генерирует исключение, даже если он должен:

try { $dt = new \DateTime('0000-00-00 00:00:00'); } 
catch (Exception $e) { var_dump($e); }
var_dump($dt); 
/* result:
object(DateTime)#1 (3) {
  ["date"]=>
  string(20) "-0001-11-30 00:00:00"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
*/

Другие функции обрабатывают этот ввод как ошибку:

var_dump(strtotime('0000-00-00 00:00:00'));  // returns: bool(false)

Кажется, что у PHP всегда были проблемы с обработкой этого случая. Примеры: Ошибка # 30190, Ошибка # 60288

Процитировать комментарии в PHP-трекере:

0000-00-00 - несуществующая дата (за день до 01-01-0001 - 31/12/-0001)