什么是正确的ISO8601格式?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么是正确的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格式提供当前时间。在Wikipedia中,正确的格式是2016-07-07T21:18:22+03:00,但有些银行在API中使用2016-07-07T21:18:22+0300格式。为什么?

答案

2016-07-07标题1:18:22 + 03:00

是正确的ISO 8601:2004表示。

2016-07-07标题1:18:22 + 0300

如果不正确,当日期和时间采用扩展格式时,区域指示符可能不是基本格式。

ISO 8601:2004 4。3日期和时间:

[...]表达式应完全采用基本格式,在这种情况下,使用所需表达式所需的最小分隔符数,或完全采用扩展格式,在这种情况下,应使用额外的分隔符[...]

更新1:

ISO 8601规定了三种不同的日期表示:日历,序数和周日期。 Theese可以格式化为基本格式(最小分隔数)或扩展格式(包括附加分隔符的基本格式的扩展)。 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
另一答案

即使使用DateTime :: ATOM,在给出毫秒时,php仍然无法正确解释ISO8601。

$d=DateTime::createFromFormat(DateTime::ATOM,"2018-01-10T01:00:00.000Z"); 
// null

或使用碳:

echo CarbonCarbon::createFromFormat(CarbonCarbon::ATOM,"2018-01-10T01:00:00.000Z","UTC");
// InvalidArgumentException with message 'The timezone could not be found in the database'

最好的方法是让Carbon或datetime自己解决:

$d = new CarbonCarbon("2018-01-10T01:00:00.000Z");
// -> 2018-01-10 01:00:00
$d = new CarbonCarbon("2018-01-10T01:00:00Z");
// -> 2018-01-10 01:00:00

以上是关于什么是正确的ISO8601格式?的主要内容,如果未能解决你的问题,请参考以下文章

ISO 8601:时间和日期的表示标准

Zend_Date 和 ISO_8601 格式的问题

ISO 8601 和 RFC 3339 日期格式有啥区别?

如何解析 ISO 8601 格式的日期?

iOS-时间格式ISO 8601

了解一下ISO 8601是什么