Какой правильный формат ISO8601?

Зачем

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. Зачем?

1

Решение

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
0

Другие решения

Тем не менее, 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
0

По вопросам рекламы [email protected]