代码之家  ›  专栏  ›  技术社区  ›  Josh Glover

如何编写一个带有时区但没有时间组件的ISO8601日期

  •  2
  • Josh Glover  · 技术社区  · 6 年前

    ISO 8601 datetime

    2018-09-07T05:28:42Z
    

    但是,我需要在我的系统中表示一些日期,其中精度是天,而不是秒,这意味着它将是一个 ISO 8601 calendar date

    2018-09-07
    

    在维基百科关于这个标准的文章中(我不能访问这个标准本身,因为你必须为这个特权付费),在讨论日期时没有提到时区。它确实谈到了省略部分时间:

    为了更简洁,可以从基本或扩展时间格式中省略秒或分和秒,但精度降低:[hh]:[mm]、[hh][mm]和[hh]是由此产生的精度降低的时间格式。

    由此看来,你不能省略小时,所以我不能这样写日历日期:

    2018-09-07TZ
    

    看来我能做的就是把时间缩短到小时:

    2018-09-07T00Z
    

    有什么建议吗?

    3 回复  |  直到 6 年前
        1
  •  9
  •   Matt Johnson-Pint    6 年前

    正式地说,iso8601规范不允许有时区的日期,除非提供了时间。因此,如果您希望保持ISO 8601兼容,则不能提供除年、月和日以外的仅日期值的附加信息(不使用时间间隔-下面将进一步提及)。

    一种格式 允许在 xs:date 类型。在那里,它是可选的,并且会紧接着一天,例如 2018-09-07Z . XSD规范调用 Section D.3 Deviations from ISO 8601 Formats

    D.3.4允许时区
    数据类型date、gYearMonth、gMonthDay、gDay、gMonth和gYear permit 可选的尾随时区说明。

    calendar image

    指向日历上的任何给定日期都不能告诉我任何关于时区的信息。我可以把日历给其他时区的人,他们仍然可以谈论日期。很简单,如果我们同时指向“今天”,我们 不是指同一个日期。因此,时区只适用于我们应用时间上下文时,无论是“现在”还是特定的时间上下文。

    然而,我们确实倾向于根据时区来合理化某一天的所有时间点。在您的示例中,“UTC日”。我们的意思是它从 T00:00Z 一天,一天之前 T00:00时 下一个。这通常是像这样的事情背后的推理

    如果我们希望严格遵守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 . 在我看来,这是最接近的完全符合iso8601标准的方式来表示以UTC解释的整个日期。

    2018-09-07Z 即使它没有严格遵守。只要确保您的数据的所有使用者都同意这种格式。如果你做不到,就过去 2018-09-07 utcDate .

        2
  •  0
  •   Jerry Coffin    6 年前

    在我看来,这里的首要问题似乎是你用什么来写日期/时间。

    例如,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
    

    如果你真正的问题是它是否符合ISO8601中指定的格式,我相信答案是否定的,但是它很容易产生。

    哦,至少在我看来,是的,带时区的约会是完全有意义的。即使你只关心日期,时区会告诉你这个日期相对于地球上其他地方的开始/结束时间,所以如果我说“2019年1月1日PDT”,伦敦的某个人知道这个日期与他当地的日期相差7小时。

        3
  •  -1
  •   PowerStat    6 年前

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

    顺便说一句,W3C也有一些关于ISO8601的例子 Date and Time Formats . 最后但并非最不重要的一点是,您可以随时编写自己的解析器,例如 Antlr .

    还要记住,时区可能会随着时间的推移而改变,例如正常时间和夏季时间。