RFC3339 字符串中的有效日期时间分隔符是什么?

What are valid date-time separators in RFC3339 strings?

我很困惑 RFC3339 standard 中允许的时间 separator/designator。我所说的时间分隔符是指在日期和时间之间划界的字符序列。

标准规定了 in section 5.6 不明确或相互矛盾的不同内容。首先,它说完整日期时间的生产规则是这样的:

date-time = full-date "T" full-time

意思是日期和时间之间的分隔符是大写T。紧随其后的是:

  NOTE: Per [ABNF] and ISO8601, the "T" and "Z" characters in this
  syntax may alternatively be lower case "t" or "z" respectively

意思是大写T可能是小写t。它与 ABNF 冲突,但好吧,它在我看来仍然在合理的范围内。然后声明如下

  NOTE: ISO 8601 defines date and time separated by "T".
  Applications using this syntax may choose, for the sake of
  readability, to specify a full-date and full-time separated by
  (say) a space character.

这很令人困惑。这是否不仅允许 space 字符,还允许任何其他字符?这就是 say 所暗示的意思。还是 this syntax 引用了 ISO8601 并不必要地描述了其他标准的细节?

换句话说,以下是有效的 RFC3339 字符串吗?

Meaning the upper case T may be a lower case t. It conflicts with the ABNF, [...]

没有。请参阅 RFC 2234 的 2.3 Terminal Values

Literal text strings are interpreted as a concatenated set of
printable characters.

   NOTE:     ABNF strings are case-insensitive and
             the character set for these strings is us-ascii.

所以这里允许使用t

  NOTE: ISO 8601 defines date and time separated by "T".
  Applications using this syntax may choose, for the sake of
  readability, to specify a full-date and full-time separated by
  (say) a space character.

Which is very confusing. Does this allow not only a space character but anything?

此“偏差”用于在显示时对用户可读性。所以当值以某种形式显示给用户时,可以显示为:

  • 2020-09-07 20:26:03.623359300+02:00
  • 2020-09-07, 20:26:03.623359300+02:00

这样用户可能更容易看到日期和时间之间的清晰 space,因此他们不必寻找 Tt字符找到分离。这确实是一个模糊的句子,因为它基本上意味着应用程序可以做任何事情。

回答您的问题:根据 RFC 3339,这些列出的日期格式无效。

简短回答:T(或 t 作为不鼓励的选择)。

尽可能多地阅读后,我发现时间分隔符必须是 Tt。以这种方式思考的首先是 this thread in the GNU lists F. Alexander Njemz 联系了 RFC3339 Graham Klyne 和 Chris Newman 的作者,询问 T 是否是强制性的,并得到了 Klyne 先生的回应:

In short: "yes"

Per section 5.5, the intent in this draft was to specify a timestamp format using elements from and compatible with 8601, but eliminating as far as reasonable any variations that could make timestamp data harder to process. This includes making the 'T' mandatory in date+time values.

#g

为了清楚起见,section 5.5:

Simplicity is achieved by making most fields and punctuation mandatory.

这显然与 non-mandatory T 冲突,强烈让我认为该有问题的段落中的 this syntax 指的是 ISO8601 而不是 RFC3339。

对于那些想阅读更多内容的人,这里有一些关于这个特定点造成的混乱的链接:

当然还有不同的实现。例如,GNU Date 的开发者选择使用 space 字符:

$ date --rfc-3339=seconds
2020-09-14 14:53:51+02:00