ISO 8601和RFC 3339似乎是网络上常见的两种格式。我应该用一种而不是另一种吗?一个只是一个延伸吗?我真的有必要那么在乎吗?


你没必要那么在意。RFC 3339,就其本身而言,是一套源自ISO 8601的标准。虽然有一些细微的区别,但它们都在RFC 3339中列出了。我可以在这里把它们都讲一遍,但如果你担心的话,你可能最好自己阅读文档:

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


一个只是一个延伸吗?

Pretty much, yes - RFC 3339 is listed as a profile of ISO 8601. Most notably RFC 3339 specifies a complete representation of date and time (only fractional seconds are optional). The RFC also has some small, subtle differences. For example truncated representations of years with only two digits are not allowed -- RFC 3339 requires 4-digit years, and the RFC only allows a period character to be used as the decimal point for fractional seconds. The RFC also allows the "T" to be replaced by a space (or other character), while the standard only allows it to be omitted (and only when there is agreement between all parties using the representation).

我不会太担心这两者之间的差异,但在你的用例偶然遇到它们时,它值得你看一看:

RFC 3339 关于ISO 8601的维基百科条目 https://ijmacd.github.io/rfc3339-iso8601/有一个测试文件生成器来演示差异以及您的代码如何处理它们


RFC 3339主要是ISO 8601的配置文件,但实际上与它不一致,因为它借用了RFC 2822的“-00:00”时区规范。这在维基百科的文章中有描述。


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不允许这样做。

关于你的问题:

一个只是一个延伸吗?

不。如上所示,每个标准都支持另一个标准不支持的语法变化。所以一种语法不是另一种语法的超集或扩展。

我应该用一种而不是另一种吗?

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

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

我真的有必要那么在乎吗?

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


实际上获取ISO规范似乎很困难和/或昂贵。这就是为什么我们看到许多链接到维基百科页面的原因。

仅仅因为这个原因,我更喜欢RFC3339:你可以直接去主源。