Зачем
echo date('c');
не равен
$datetime = new DateTime();
echo $datetime->format(DateTime::ISO8601);
Результат:
2016-07-07T21:18:22+03:00
2016-07-07T21:18:22+0300
Оба должны указывать текущее время в формате ISO8601. В Википедия правильный формат 2016-07-07T21:18:22+03:00
но некоторые банки используют 2016-07-07T21:18:22+0300
формат в API. Зачем?
2016-07-07T21: 18: 22 + 03: 00
Является ли правильное представление ISO 8601: 2004.
2016-07-07T21: 18: 22 + 0300
Неправильно, указатель зоны может быть не в базовом формате, когда дата и время дня в расширенном формате.
ISO 8601: 2004 4.3 Дата и время дня:
[…] выражение должно быть полностью в базовом формате, в
в этом случае минимальное количество разделителей, необходимых для требуемого
выражение используется или полностью в расширенном формате, в этом случае
должны использоваться дополнительные разделители […]
Обновление 1:
ISO 8601 определяет три разных представления даты: календарная, порядковая и недельная. Они могут быть отформатированы либо в базовом формате (минимальное количество разделителей), либо в расширенном формате (расширение базового формата, включающего дополнительные разделители). ISO 8601 требует, чтобы полученное выражение было либо последовательно в базовом формате, либо последовательно в расширенном формате.
Комбинация календарной даты и времени суток по местному времени с отличиями от UTC:
2016-07-07T21:18:22+03:00 (extended format)
20160707T211822+0300 (basic format)
Комбинация порядковой даты и времени суток по местному времени с отличиями от UTC:
2016-189T21:18:22+03:00 (extended format)
2016189T211822+0300 (basic format)
Сочетание даты недели и времени суток по местному времени с отличиями от UTC:
2016-W27-4T21:18:22+03:00 (extended format)
2016W274T211822+0300 (basic format)
Все вышеперечисленные представления представляют одну и ту же дату и время суток по местному времени, с отличием от UTC (и мгновенного). Если API документирует, что он принимает дату ISO 8601 с указанием времени суток и обозначение зоны (также известное как полное представление), он должен принять все вышеперечисленные представления, чтобы соответствовать ISO 8601.
Обновление 2:
Большинство ошибок, с которыми я столкнулся, связаны с использованием strftime()
выводить дату и время по ISO 8601 по местному времени с отличиями от UTC в расширенном формате. Стандарт strftime()
может выводить только совместимые представления в базовом формате из-за ограничений в z
спецификатор конверсии:
Комбинация календарной даты и времени суток по местному времени с отличиями от UTC:
Format: Example:
%Y%m%dT%H%M%S%z 20160707T211822+0300
Комбинация порядковой даты и времени суток по местному времени с отличиями от UTC:
Basic format: Example:
%Y%jT%H%M%S%z 2016189T211822+0300
Сочетание даты недели и времени суток по местному времени с отличиями от UTC:
Basic format: Example:
%GW%V%uT%H%M%S%z 2016W274T211822+0300
Реализация GNU strftime поддерживает :
флаг между процентами и z
спецификатор преобразования, чтобы указать, что указатель зоны должен быть отформатирован в расширенном формате:
Комбинация календарной даты и времени суток по местному времени с отличиями от UTC:
Format: Example:
%Y-%m-%dT%H:%M:%S%:z 2016-07-07T21:18:22+03:00
Комбинация порядковой даты и времени суток по местному времени с отличиями от UTC:
Format: Example:
%Y-%jT%H:%M:%S%:z 2016-189T21:18:22+03:00
Сочетание даты недели и времени суток по местному времени с отличиями от UTC:
Format: Example:
%G-W%V-%uT%H:%M:%S%:z 2016-W27-4T21:18:22+03:00
Тем не менее, PHP не интерпретирует ISO8601 правильно, когда даются миллисекунды, даже с DateTime :: ATOM.
$d=DateTime::createFromFormat(DateTime::ATOM,"2018-01-10T01:00:00.000Z");
// null
или используя углерод:
echo Carbon\Carbon::createFromFormat(Carbon\Carbon::ATOM,"2018-01-10T01:00:00.000Z","UTC");
// InvalidArgumentException with message 'The timezone could not be found in the database'
Лучший способ — позволить Carbon или datetime разобраться самому:
$d = new Carbon\Carbon("2018-01-10T01:00:00.000Z");
// -> 2018-01-10 01:00:00
$d = new Carbon\Carbon("2018-01-10T01:00:00Z");
// -> 2018-01-10 01:00:00