ISO 8601规范中要求提供时间时区信息,否则日期不能包含时区信息。因此,如果您希望保持ISO 8601兼容性,对于仅包含年、月和日的日期值,您不能提供额外的信息(除非使用下面提到的时间间隔)。
允许这种信息的一种格式是XML Schema(也称为“XSD”),在xs:date
类型中,可以选择提供时间信息,直接跟在日期之后,例如2018-09-07Z
。XSD规范在D.3 异常状况与ISO 8601格式不符中指出:
D.3.4 允许时区
数据类型日期、gYearMonth、gMonthDay、gDay、gMonth和gYear的词法表示允许可选的尾随时区说明。
我知道你没有询问关于XSD的内容,但这是我所知道的唯一一个自由在线可用的规范参考,它把日期上的时区标注为ISO 8601的一种偏差。
正如其他人指出的那样,考虑带有时区的日期是一件棘手的事情。在许多方面,仅包含日期值是不明确的。请考虑我向您展示的这个日历:
![日历图片](https://istack.dev59.com/66ctP.webp)
在这个日历上标记一个日期并不能告诉我任何关于时区的信息。我可以把这个日历交给不同时区的人,他们仍然能谈论日期。只是如果我们同时指着“今天”,我们可能不是指着同一天。因此,时区只有在应用时间上下文(无论是“现在”还是特定的时间)时才适用。
然而,我们往往会根据某一天的所有时间点来进行理性思考,以某个时区为基准,比如你举的例子,“UTC Day”。我们的意思是它从一天的T00:00Z
开始,到下一天的T00:00Z
之前结束。这通常是像xs:date
允许使用时区偏移量的原因。
如果我们想要严格遵守ISO 8601标准并表示相同的含义,我们必须提供一系列的日期+时间值,称为ISO 8601规范第4.4节中的“时间间隔”,并用斜杠(/
)字符分隔。这样的值示例为:2018-09-07T00:00Z/2018-09-08T00:00Z
。但要小心,因为ISO 8601没有说明结束日期应该如何被解释(是包括还是不包括在内)。详见此处。
另一种ISO 8601表示间隔的方式允许一个开始时间和一个持续时间组件,例如2018-09-07T00:00Z/P1D
。对我来说,这似乎是最接近完全符合ISO 8601标准的以UTC解释整个日期的方式。
不过,就我个人而言,如果我需要在日期中传达时区信息,即使它不严格符合规范,我也会使用2018-09-07Z
。只要确保数据的所有消费者都同意这种格式。如果你无法做到这一点,只需传递2018-09-07
并将字段命名为utcDate
之类的名称。