How can I write an ISO 8601 date with a timezone but no time component

感情迁移 提交于 2021-02-06 12:56:05

问题


An ISO 8601 datetime with a timezone is formatted like this:

2018-09-07T05:28:42Z

However, I need to represent some dates in my system where the precision is days, not seconds, which means that it would be an ISO 8601 calendar date. Calendar dates are formatted like this:

2018-09-07

In the Wikipedia article about the standard (I don't have access to the standard itself, as you have to pay for that privilege), there is no mention of timezone when discussing dates. It does talk about omitting parts of the time:

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.

From this, it seems that you cannot omit hours, so I could not write a calendar date like this:

2018-09-07TZ

It appears that the best I can do is truncating down to the hour:

2018-09-07T00Z

I don't want to do this if I can avoid it, however, as I am adding more precision to a date than is really there. The date means "sometime during the day of 07 September, 2018 in the UTC timezone", not "sometime during the midnight hour of 07 September, 2018 in the UTC timezone".

Any suggestions?


回答1:


Officially, the ISO 8601 spec does not allow for a date with a time zone unless a time is provided. Thus, if you wish to remain ISO 8601 compliant, you cannot provide additional information for date-only values than year, month, and day (without resorting to time intervals - mentioned further below).

One format that does allow for this is XML Schema (aka "XSD"), in the 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.

I realize you weren't asking about XSD, but this the only normative reference I'm aware of that's freely available online that calls out the time zone on a date is a deviation from ISO 8601.

As others have pointed out - thinking about a date with a time zone is a tricky thing. In many aspects, a date-only value is ambiguous. Consider if I presented you a calendar such as this one:

Pointing at any given date on this calendar doesn't tell me anything about time zones. I can give the calendar to someone in a different time zone and they will still be able to talk about dates. It's simply that if we both point at "today" simultaneously, we might not be pointing at the same date. Thus, time zones only apply when we apply a time context, whether "now" or a specific one.

However, we do tend to rationalize about all points in time on a given day in terms of a time zone. In your example, the "UTC Day". We mean that it runs from T00:00Z of one day, to just before T00:00Z of the next. This is generally the reasoning behind things like xs:date allowing a time zone offset.

If we wanted to be strictly ISO 8601 compliant and represent the same meaning, we'd have to provide a range of date+time values, which are called "time intervals" in section 4.4 of the ISO 8601 spec, and are separated with a forward slash (/) character. An example of such a value would be 2018-09-07T00:00Z/2018-09-08T00:00Z. However, be careful because ISO 8601 says nothing about whether the end date should be interpreted inclusively or exclusively. More on that here.

Another ISO 8601 representation of an interval allows for a start time and a duration component, such as 2018-09-07T00:00Z/P1D. This feels to me like the closest fully ISO 8601 compliant way to represent a whole date interpreted in UTC.

Still, personally, if I needed to convey time zone with a date, I would use 2018-09-07Z even if it wasn't strictly compliant. Just make sure all consumers of your data agree on this format. If you can't do that, just pass 2018-09-07 and name your field something like utcDate.




回答2:


The primary question here seems (to me) what you're using to write out your date/time.

Just for example, in C++ you could do:

time_t n = std::time(NULL);

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

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

This produces an output like:

2018-09-07 -0700

If your real question is whether this corresponds to a format specified in ISO 8601, I believe the answer is no. But it's fairly easy to produce it nonetheless.

Oh, and at least IMO, yes just a date with a time-zone can make perfectly good sense. Even though you only care about the date, the time zone tells you when that date begins/ends relative to other places on earth, so if I say "1 January 2019 PDT", somebody in (say) London knows that the date in question is offset by 7 hours from his local date.




回答3:


A date with a timezone makes no sense, because timezones adjust the hours/minutes within a day. Maybe you have a date and a separate timezone that you need for something different? For the case that you need the timezone for the international date line, you also need the time in format of hours:minutes without that the timezone would not make sense.

Btw. the W3C has also some examples about ISO8601 Date and Time Formats. Last but not least you can always write your own parser for example with Antlr.

Also keep in mind that timezones might/will change over time - for example normal time vs. summer time.



来源:https://stackoverflow.com/questions/52215961/how-can-i-write-an-iso-8601-date-with-a-timezone-but-no-time-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!