如何编写带有时区但没有时间组件的 ISO 8601 日期
How can I write an ISO 8601 date with a timezone but no time component
带有时区的 ISO 8601 datetime 格式如下:
2018-09-07T05:28:42Z
但是,我需要在我的系统中表示一些精度为天而不是秒的日期,这意味着它将是 ISO 8601 calendar date。日历日期格式如下:
2018-09-07
在有关该标准的维基百科文章中(我无权访问该标准本身,因为您必须为该特权付费),在讨论日期时没有提及时区。它确实谈到了省略部分时间:
Either the seconds, or the minutes and seconds, may be omitted from the basic or extended time formats for greater brevity but decreased accuracy: [hh]:[mm], [hh][mm] and [hh] are the resulting reduced accuracy time formats.
由此看来,你不能省略小时,所以我不能这样写日历日期:
2018-09-07TZ
看来我能做的最好的事情就是缩短到小时:
2018-09-07T00Z
但是,如果可以避免,我不想这样做,因为我为日期增加了比实际更精确的日期。日期表示 "sometime during the day of 07 September, 2018 in the UTC timezone",而不是 "sometime during the midnight hour of 07 September, 2018 in the UTC timezone"。
有什么建议吗?
带时区的日期没有意义,因为时区会在一天内调整 hours/minutes。也许你有一个日期和一个单独的时区,你需要不同的东西?如果您需要国际日期变更线的时区,您还需要格式为 hours:minutes 的时间,否则时区将没有意义。
顺便说一句。 W3C 也有一些关于 ISO8601 Date and Time Formats 的例子。
最后但同样重要的是,您始终可以编写自己的解析器,例如 Antlr.
另请记住,时区 might/will 会随着时间而变化 - 例如正常时间与夏令时。
这里的主要问题(对我来说)似乎是你用什么写出你的date/time。
举个例子,在 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 上,是的,只有带时区的日期就非常有意义。即使你只关心日期,时区也会告诉你那个日期 begins/ends 相对于地球上其他地方的时间,所以如果我说“2019 年 1 月 1 日 PDT”,(比如说)伦敦的某个人知道这个日期有问题的是从他的本地日期偏移 7 小时。
正式地,ISO 8601 规范不允许带有时区的日期,除非提供了时间。因此,如果您希望保持 ISO 8601 合规性,则不能为仅日期值提供除年、月和日之外的其他信息(不求助于时间间隔 - 下文将进一步提及)。
允许的一种格式是 XML 架构(又名 "XSD"),在 xs:date
type. There, it is optional, and would immediately follow the day, such as 2018-09-07Z
. The XSD spec calls out in Section D.3 Deviations from ISO 8601 Formats:
D.3.4 Time zone permitted
The lexical representations for the
datatypes date, gYearMonth, gMonthDay, gDay, gMonth and gYear permit
an optional trailing time zone specificiation.
我知道你不是在问 XSD,但这是我所知道的唯一可在网上免费获得的、标明日期时区的规范性参考,与 ISO 8601 有偏差。
正如其他人指出的那样 - 考虑带时区的约会是一件棘手的事情。在许多方面,仅日期值是不明确的。考虑一下我是否向您展示了这样一个日历:
指向此日历上的任何给定日期都不会告诉我有关时区的任何信息。我可以把日历给不同时区的人,他们仍然可以谈论日期。很简单,如果我们同时指向 "today",我们 可能 不会指向同一日期。因此,时区仅在我们应用时间上下文时适用,无论是 "now" 还是特定时间上下文。
但是,我们确实倾向于根据时区合理化给定日期的所有时间点。在您的示例中,"UTC Day"。我们的意思是它从一天的 T00:00Z
运行到下一天的 T00:00Z
之前。这通常是 xs:date
允许时区偏移的原因。
如果我们想严格符合 ISO 8601 并表示相同的含义,我们必须提供一系列日期+时间值,在 ISO 8601 规范的第 4.4 节中称为 "time intervals" , 并用正斜杠 (/
) 字符分隔。这种值的一个例子是 2018-09-07T00:00Z/2018-09-08T00:00Z
。但是,要小心,因为 ISO 8601 说 nothing 关于结束日期应该被解释为包含还是排除。 .
间隔的另一种 ISO 8601 表示允许开始时间和 持续时间 组件,例如 2018-09-07T00:00Z/P1D
。在我看来,这就像最接近完全符合 ISO 8601 标准的方式来表示以 UTC 解释的整个日期。
不过,就我个人而言,如果我需要用日期来传达时区,我会使用 2018-09-07Z
,即使它不严格符合要求。只需确保您数据的所有消费者都同意这种格式。如果你不能这样做,只需传递 2018-09-07
并将你的字段命名为 utcDate
.
带有时区的 ISO 8601 datetime 格式如下:
2018-09-07T05:28:42Z
但是,我需要在我的系统中表示一些精度为天而不是秒的日期,这意味着它将是 ISO 8601 calendar date。日历日期格式如下:
2018-09-07
在有关该标准的维基百科文章中(我无权访问该标准本身,因为您必须为该特权付费),在讨论日期时没有提及时区。它确实谈到了省略部分时间:
Either the seconds, or the minutes and seconds, may be omitted from the basic or extended time formats for greater brevity but decreased accuracy: [hh]:[mm], [hh][mm] and [hh] are the resulting reduced accuracy time formats.
由此看来,你不能省略小时,所以我不能这样写日历日期:
2018-09-07TZ
看来我能做的最好的事情就是缩短到小时:
2018-09-07T00Z
但是,如果可以避免,我不想这样做,因为我为日期增加了比实际更精确的日期。日期表示 "sometime during the day of 07 September, 2018 in the UTC timezone",而不是 "sometime during the midnight hour of 07 September, 2018 in the UTC timezone"。
有什么建议吗?
带时区的日期没有意义,因为时区会在一天内调整 hours/minutes。也许你有一个日期和一个单独的时区,你需要不同的东西?如果您需要国际日期变更线的时区,您还需要格式为 hours:minutes 的时间,否则时区将没有意义。
顺便说一句。 W3C 也有一些关于 ISO8601 Date and Time Formats 的例子。 最后但同样重要的是,您始终可以编写自己的解析器,例如 Antlr.
另请记住,时区 might/will 会随着时间而变化 - 例如正常时间与夏令时。
这里的主要问题(对我来说)似乎是你用什么写出你的date/time。
举个例子,在 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 上,是的,只有带时区的日期就非常有意义。即使你只关心日期,时区也会告诉你那个日期 begins/ends 相对于地球上其他地方的时间,所以如果我说“2019 年 1 月 1 日 PDT”,(比如说)伦敦的某个人知道这个日期有问题的是从他的本地日期偏移 7 小时。
正式地,ISO 8601 规范不允许带有时区的日期,除非提供了时间。因此,如果您希望保持 ISO 8601 合规性,则不能为仅日期值提供除年、月和日之外的其他信息(不求助于时间间隔 - 下文将进一步提及)。
允许的一种格式是 XML 架构(又名 "XSD"),在 xs:date
type. There, it is optional, and would immediately follow the day, such as 2018-09-07Z
. The XSD spec calls out in Section D.3 Deviations from ISO 8601 Formats:
D.3.4 Time zone permitted
The lexical representations for the datatypes date, gYearMonth, gMonthDay, gDay, gMonth and gYear permit an optional trailing time zone specificiation.
我知道你不是在问 XSD,但这是我所知道的唯一可在网上免费获得的、标明日期时区的规范性参考,与 ISO 8601 有偏差。
正如其他人指出的那样 - 考虑带时区的约会是一件棘手的事情。在许多方面,仅日期值是不明确的。考虑一下我是否向您展示了这样一个日历:
指向此日历上的任何给定日期都不会告诉我有关时区的任何信息。我可以把日历给不同时区的人,他们仍然可以谈论日期。很简单,如果我们同时指向 "today",我们 可能 不会指向同一日期。因此,时区仅在我们应用时间上下文时适用,无论是 "now" 还是特定时间上下文。
但是,我们确实倾向于根据时区合理化给定日期的所有时间点。在您的示例中,"UTC Day"。我们的意思是它从一天的 T00:00Z
运行到下一天的 T00:00Z
之前。这通常是 xs:date
允许时区偏移的原因。
如果我们想严格符合 ISO 8601 并表示相同的含义,我们必须提供一系列日期+时间值,在 ISO 8601 规范的第 4.4 节中称为 "time intervals" , 并用正斜杠 (/
) 字符分隔。这种值的一个例子是 2018-09-07T00:00Z/2018-09-08T00:00Z
。但是,要小心,因为 ISO 8601 说 nothing 关于结束日期应该被解释为包含还是排除。
间隔的另一种 ISO 8601 表示允许开始时间和 持续时间 组件,例如 2018-09-07T00:00Z/P1D
。在我看来,这就像最接近完全符合 ISO 8601 标准的方式来表示以 UTC 解释的整个日期。
不过,就我个人而言,如果我需要用日期来传达时区,我会使用 2018-09-07Z
,即使它不严格符合要求。只需确保您数据的所有消费者都同意这种格式。如果你不能这样做,只需传递 2018-09-07
并将你的字段命名为 utcDate
.