如何编写带有时区但没有时间组件的ISO 8601日期
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何编写带有时区但没有时间组件的ISO 8601日期相关的知识,希望对你有一定的参考价值。
带有时区的ISO 8601 datetime的格式如下:
2018-09-07T05:28:42Z
但是,我需要在我的系统中表示一些日期,其中精度是天,而不是秒,这意味着它将是一个ISO 8601 calendar date。日历日期的格式如下:
2018-09-07
在Wikipedia关于标准的文章中(我无法访问标准本身,因为您必须为该特权付费),在讨论日期时没有提及时区。它确实谈到省略部分时间:
为了更简洁,可以省略基本或扩展时间格式的秒数或分钟数和秒数,但精度会降低:[hh]:[mm],[hh] [mm]和[hh]导致精度降低时间格式。
从这看来,似乎你不能省略小时,所以我不能写这样的日历日期:
2018-09-07TZ
似乎我能做的最好的事情是截断到小时:
2018-09-07T00Z
但是,如果我可以避免它,我不想这样做,因为我正在为日期添加比实际更多的精度。日期表示“在UTC时区的2018年9月7日的某个时间”,而不是“在UTC时区的2018年9月7日午夜的某个时间”。
有什么建议?
正式地,ISO 8601规范不允许带有时区的日期,除非提供时间。因此,如果您希望保持符合ISO 8601标准,则无法提供仅包含日期值的其他信息,而不是年,月和日(不依赖于时间间隔 - 下面进一步提及)。
允许这种情况的一种格式是xs:date
类型的XML Schema(又名“XSD”)。在那里,它是可选的,并且会立即跟随当天,例如2018-09-07Z
。 XSD规范在Section D.3 Deviations from ISO 8601 Formats中调用:
D.3.4允许的时区 数据类型date,gYearMonth,gMonthDay,gDay,gMonth和gYear的词法表示允许可选的尾随时区细分。
我意识到你并不是在询问XSD,但这是我所知道的唯一规范性参考,它可以在网上免费获得,在日期上调出时区是与ISO 8601的偏差。
正如其他人所指出的那样 - 考虑与时区约会是一件棘手的事情。在许多方面,仅日期值是不明确的。考虑一下我是否向您展示了这样的日历:
指向此日历上的任何给定日期并不会告诉我任何有关时区的信息。我可以将日历提供给不同时区的某个人,他们仍然可以谈论日期。只是如果我们同时指向“今天”,我们可能不会指向同一个日期。因此,时区仅适用于我们应用时间上下文,无论是“现在”还是特定时间。
但是,我们确实倾向于按照时区对某一天的所有时间点进行合理化。在您的示例中,“UTC日”。我们的意思是它从一天的T00:00Z
到下一个的T00:00Z
之前。这通常是xs:date
允许时区偏移的原因。
如果我们想要严格符合ISO 8601并且代表相同的含义,我们必须提供一系列日期+时间值,在ISO 8601规范的第4.4节中称为“时间间隔”,并用正斜杠(/
)字符。这样一个值的一个例子是2018-09-07T00:00Z/2018-09-08T00:00Z
。但是,要小心,因为ISO 8601没有说明是否应该包含或完全解释结束日期。 More on that here。
间隔的另一个ISO 8601表示允许开始时间和持续时间分量,例如2018-09-07T00:00Z/P1D
。这对我来说就像最接近完全符合ISO 8601的方式来表示以UTC解释的整个日期。
不过,就个人而言,如果我需要传送带有约会的时区,我会使用2018-09-07Z
,即使它没有严格遵守。只需确保您的数据的所有消费者都同意此格式。如果你不能这样做,只需通过2018-09-07
并将你的字段命名为utcDate
。
这里的主要问题似乎(对我而言)你用什么来写出你的日期/时间。
例如,在C ++中你可以做到:
time_t n = std::time(NULL);
tm *now = std::localtime(&n);
std::cout << std::put_time(now, "%F %z") << '
';
这会产生如下输出:
2018-09-07 -0700
如果你真正的问题是这是否符合ISO 8601中规定的格式,我相信答案是否定的。但是,生产它仍然相当容易。
哦,至少是IMO,是的只是一个带时区的约会可以很有道理。即使您只关心日期,时区会告诉您该日期何时开始/结束相对于地球上的其他地方,所以如果我说“2019年1月1日PDT”,伦敦的某个人知道有问题的日期从当地日期起7小时抵消。
带时区的日期毫无意义,因为时区会在一天内调整小时/分钟。也许你有一个日期和一个单独的时区,你需要一些不同的东西?对于需要国际日期行的时区的情况,您还需要以小时:分钟为单位的时间,而不是时区没有意义。
顺便说一句。 W3C也有一些关于ISO8601 Date and Time Formats的例子。最后但并非最不重要的是,您总是可以使用Antlr编写自己的解析器。
另请注意,时区可能/将随时间变化 - 例如正常时间与夏季时间。
以上是关于如何编写带有时区但没有时间组件的ISO 8601日期的主要内容,如果未能解决你的问题,请参考以下文章
将 ISO 8601 日期时间字符串转换为 **Date** 对象时,如何将日期时间重新定位到当前时区?
如何在 Swift 中解析/创建格式为小数秒 UTC 时区(ISO 8601、RFC 3339)的日期时间戳?
如何在 Swift 中解析/创建格式为小数秒 UTC 时区(ISO 8601、RFC 3339)的日期时间戳?