如何编写带时区但没有时间部分的ISO 8601日期

时间:2018-09-07 05:43:19

标签: date datetime language-agnostic iso8601 timezone-offset

带有时区的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日的午夜的某个时间”。

有什么建议吗?

3 个答案:

答案 0 :(得分:5)

根据官方说法,除非提供时间,否则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的偏离。

正如其他人指出的那样-考虑带时区的日期是一件棘手的事情。在许多方面,仅日期值是不明确的。考虑一下我是否给您提供了这样的日历:

calendar image

指向该日历上的任何给定日期都不会告诉我有关时区的任何信息。我可以将日历提供给其他时区的人,他们仍然可以谈论日期。简而言之,如果我们两个人同时指向“今天”,那么我们可能不会指向同一日期。因此,时区仅在我们应用时间上下文时才适用,无论是“现在”还是特定的时间上下文。

但是,我们确实倾向于根据时区对给定日期的所有时间点进行合理化处理。在您的示例中,为“ 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

答案 1 :(得分:0)

在我看来,这里的主要问题是您用来写出日期/时间的东西。

例如,在C ++中,您可以执行以下操作:

time_t n = std::time(NULL);

tm *now = std::localtime(&n);

std::cout << std::put_time(now, "%F %z") << '\n';

这将产生如下输出:

2018-09-07 -0700

如果您真正的问题是这是否符合ISO 8601中指定的格式,我相信答案是否定的。但是仍然可以很容易地生产它。

哦,至少是IMO,是的,只有一个带时区的日期才是非常合理的。即使您只关心日期,时区也会告诉您该日期相对于地球上其他地方的开始/结束时间,因此,如果我说“ PDT 2019年1月1日”,那么(说)伦敦的某人知道该日期是有问题的从他的本地日期起偏移了7个小时。

答案 2 :(得分:-1)

带有时区的日期没有意义,因为时区会调整一天中的小时/分钟。也许您有一个日期和一个单独的时区,您需要一些不同的东西?对于需要国际日期变更线的时区的情况,还需要使用小时:分钟格式的时间,如果没有该时区就没有意义。

顺便说一句。 W3C还提供了一些有关ISO8601 Date and Time Formats的示例。 最后但并非最不重要的一点是,您始终可以使用Antlr编写自己的解析器。

还请记住,时区可能会/将随着时间而改变-例如正常时间与夏令时。