PHP日期格式:ISO8601与ISO8601_EXPANDED的区别

5

背景

我想从 PHP 8.2 的 DateTime 对象中生成一个 ISO-8601 字符串。 Date 类有 两个相关的预定义常量 用于 date_format() 函数:

  • DATE_ISO8601 - "Y-m-d\\TH:i:sO" 注意:此格式与 ISO-8601 不兼容,但出于向后兼容性的原因保留了这种方式。使用 DateTimeInterface::ISO8601_EXPANDED、DateTimeInterface::ATOM 以与 ISO-8601 兼容。(参考 ISO8601:2004 第 4.3.3 条款 d)

  • DATE_ISO8601_EXPANDED - "X-m-d\\TH:i:sP" 此格式允许年份范围超出 ISO-8601 的正常范围 0000-9999,始终包含符号字符。它还解决了时区部分(+01:00)与 ISO-8601 兼容的问题。

问题

DATE_ISO8601_EXPANDED 格式在字符串前面添加了一个 + 字符,但这个字符并不被其他语言(特别是 Swift)中的 ISO8601 解析器所识别:

+2023-03-29T05:54:21+00:00

DATE_ISO8601 的输出为:

2023-03-29T05:54:21+0000

我无法确定关于DATE_ISO8601的警告是什么意思。它是指:

  1. "该格式不符合ISO8601的最新修订版本,因此您应该使用“扩展”变体。"

还是

  1. "该格式存在错误,有时会产生无效的ISO8601输出,因此您应该使用扩展格式。"

令人捧腹的是,ISO 8601的第4节 没有公开出售, 所以我无法阅读它。但是,“扩展”格式似乎也不是标准的ISO8601,因为规格说明只在年份大于9999时要求前导+符号。


只是澄清一下,我无法确定关于DATE_ISO8601的警告是什么意思 - 你所说的警告是什么? - Nigel Ren
@nigelren 在文档中的注释: "此格式与ISO-8601不兼容,但为了向后兼容性而保留。" - Bryan
1
有趣的是,x将是可选的 +,而 X始终包含 +。如果您想要与其他解析器兼容,使用自己的格式字符串可能会起到作用。当然,这就错过了使用很好预定义常量的重点... - deceze
@deceze 是的,我不需要支持9999年以后的年份,所以我最初想只使用第一个常量,直到我看到文档中的这个警告,我不确定旧格式字符串是否意味着即使在范围内的年份也可能得到非规范兼容的输出。 - Bryan
1
这是此更改的相关票证:https://bugs.php.net/bug.php?id=80022 - deceze
1
就我个人而言,我总是使用'c'DATE_ATOM:https://3v4l.org/9kKch#v8.2.4 - 不管怎样,这是一个很好的问题。 - Álvaro González
1个回答

2

这个注释意味着格式DATE_ISO8601与ISO-8601根本不兼容,您不应该使用它,而应该使用DATE_ISO8601_EXPANDEDDATE_ATOM。兼容性问题与是否使用超出0000-9999年的日期无关。您可以在这里阅读更多信息。

DATE_ISO8601_EXPANDED格式与DATE_ATOM仅在年份表示上有所不同,DATE_ISO8601_EXPANDED使用'X'而不是'Y'

"Y-m-d\\TH:i:sP"
"X-m-d\\TH:i:sP"

如果您不需要在0-9999之外的值中使用扩展年份表示,请使用DATE_ATOM

扩展表示仅应在事先达成协议的情况下使用,这可能是为什么某些解析器无法正确处理年份前的符号的原因。虽然我也不确定DATE_ISO8601_EXPANDED是否与ISO-8601兼容,因为它提到了扩展年份表示的常数位数。

您可以在此处找到一些免费的ISO-8601链接: https://github.com/php/doc-en/pull/1619


讨论链接非常有用,谢谢! - Bryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接