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

Posted

技术标签:

【中文标题】ISO 8601 和 RFC 3339 日期格式有啥区别?【英文标题】:What's the difference between ISO 8601 and RFC 3339 Date Formats?ISO 8601 和 RFC 3339 日期格式有什么区别? 【发布时间】:2010-10-06 01:18:08 【问题描述】:

ISO 8601 和RFC 3339 似乎是网络上常见的两种格式。我应该使用其中一个吗?一个只是扩展吗?我真的需要关心那么糟糕吗?

【问题讨论】:

我已将 RFC 的链接从 ietf.org/rfc/rfc3339.txt 更改为 html 版本 tools.ietf.org/html/rfc3339。链接到 RFC 时,您应该始终链接到位于 tools.ietf.org/html 的 HTML 版本。由于部分链接,它们不仅更易于导航,而且重要的是,它们在顶部列出了任何已更新或废弃您正在阅读的 RFC 的 RFC。人们不知不觉地在 Stack Overflow 上一直引用过时的 RFC,我将继续重复这个建议,直到问题消失。 (为免生疑问,this RFC 并未过时。) 这篇文章很好地解释了它们之间的区别:ijmacd.github.io/rfc3339-iso8601 ijmacd.github.io/rfc3339-iso8601 【参考方案1】:

您不必太在意。就其本身而言,RFC 3339 是一组源自 ISO 8601 的标准。尽管存在相当多的细微差别,它们都在 RFC 3339 中进行了概述。我可以在这里全部介绍,但您可能会做得更好如果您担心,请自己阅读文档:

https://www.rfc-editor.org/rfc/rfc3339

【讨论】:

【参考方案2】:

一个只是扩展吗?

差不多,是的 - RFC 3339 被列为 ISO 8601 的配置文件。最值得注意的是 RFC 3339 指定了日期和时间的完整表示(只有小数秒是可选的)。 RFC 也有一些细微的差别。例如,不允许截断只有两位数字的年份表示 - RFC 3339 要求 4 位年份,而 RFC 仅允许将句点字符用作小数秒的小数点。 RFC 还允许将“T”替换为空格(或其他字符),而标准只允许省略它(并且仅当使用该表示的各方达成一致时)。

我不会太担心两者之间的差异,但是如果您的用例遇到它们的可能性不大,那么值得您看一看:

RFC 3339 Wikipedia entry on ISO 8601

【讨论】:

对不起 Java Guy,但这并不完全正确。您引用的附录仅供参考,限制是为了保持语法更简单。 5.6 节末尾的注释明确指出,为了便于阅读,可以使用空格,指的是前面提到的 5.2 节主题的可读性。引用:“为了可读性,使用这种语法的应用程序可以选择指定一个完整的日期和完整的时间,由(比如说)一个空格字符分隔。” @JavaGuy 您链接到的附录甚至都没有讨论 RFC 3339 语法 - 它的标题是 ISO 8601 Collected ABNF 并试图正式描述语法ISO 8601 使用 ABNF。它所说的任何内容都不应被视为有关 RFC 3339 日期时间语法的证据。 FWIW:已经在 coreutils 列表中讨论过:lists.gnu.org/archive/html/bug-coreutils/2006-05/msg00019.html “RFC 3339 要求日期和时间的完整表示” - 这是不正确的。请考虑编辑答案。为了完全确定,我给其中一位 RFC 作者发了电子邮件。回复包括“我认为如果你只想要一个日期戳,引用 [RFC3339] 'full-date' 语法产生是完全公平的游戏。......也许可能需要一个勘误表”此外,JSON Schema v7 明确支持 RFC 3339 个仅限日期(全日制)和仅限时间(全日制)的配置文件。 json-schema.org/draft-07/json-schema-release-notes.html. 我是贾斯汀(之前的评论)联系的作者(尽管不负责那里的大部分繁重工作)。我确认他的评论。一般来说,我会建议像 RFC3339 specify 之类的规范文档,而不是 require - 它是使用的上下文决定什么是 require。只要清楚意图是什么,那么引用特定的语法产生就可以了。 (这与 RFC3339 本身在选择性引用 ISO8601 时所做的并没有真正的不同。)另请参阅section 5.6 中的注释。【参考方案3】:

RFC 3339 主要是 ISO 8601 的配置文件,但实际上与从 RFC 2822 借用的“-00:00”时区规范不一致。***文章中对此进行了描述。

【讨论】:

【参考方案4】:

ISO 8601 和 RFC 3339 之间有很多不同之处。这里有一些示例可以让您了解一下:

2020-12-09T16:09:53+00:00 是符合这两个标准的日期时间值。

2020-12-09 16:09:53+00:00 使用空格分隔日期和时间。这是 RFC 3339 允许的,但 ISO 8601 不允许这样做。

2020-12-09T16:09:53-00:00 在时间偏移中指定负零。这是 RFC 3339 允许的,但 ISO 8601 不允许这样做。

20201209T160953Z 省略连字符和冒号。这在 ISO 8601 中是允许的,但在 RFC 3339 中是不允许的。

ISO 8601 允许诸如 2020-344 之类的序号日期,它代表 2020 年的第 344 天。RFC 3339 不允许这样做。

对于您的问题:

一个只是扩展吗?

没有。如上所示,每个标准都支持其他标准不支持的语法变体。因此,一种语法不是另一种语法的超集或扩展。

我应该使用一个而不是另一个吗?

当然,这取决于您的情况。一个安全的通用策略是生成对两种标准都有效的日期时间字符串。

另一个好的通用策略是使用现有的标准库来解析/格式化日期时间字符串,而不是编写自定义实现,除非您正在处理真正自定义的场景。

我真的需要那么关心吗?

好吧,这取决于你。大多数处理日期时间字符串的普通开发人员应该有较高的了解,但不需要深入细节。

【讨论】:

【参考方案5】:

实际访问 ISO 规范似乎很困难和/或昂贵。这就是为什么我们会看到许多指向***页面的链接。

仅出于这个原因,我更喜欢 RFC3339:您可以直接访问主要来源。

【讨论】:

以上是关于ISO 8601 和 RFC 3339 日期格式有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中解析/创建格式为小数秒 UTC 时区(ISO 8601、RFC 3339)的日期时间戳?

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

如何将RFC 3339日期字符串解析为ZonedDateTime?

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

Flask 学习-72.Flask-RESTX 自定义输出日期格式

日期和时间格式(ISO 8601)