Open BurntSushi opened 5 months ago
Apologies for not getting to this earlier.
This is my understanding of the rationale. One of the reasons offset: "reject"
exists is for flushing out strings that were valid times when they were serialized, but have become invalid due to political time zone changes. So if ...T02:30-04:00
or ...T02:30-05:00
were not in a DST gap when you serialized them, the exception would signal to you that they now were, and that your wall clock time has changed for that instant.
@justingrant may have a better understanding than me.
One of the reasons
offset: "reject"
exists is for flushing out strings that were valid times when they were serialized, but have become invalid due to political time zone changes.
Sorry for delayed response, I just got back from a long work trip.
@ptomato is correct. The purpose of offset: "reject"
is to detect cases where once-valid strings are now invalid. In order to support this case, we apparently lost the ability to use offset: "reject"
to parse times in a DST gap. I'm not 100% sure this is the best tradeoff, but like many things related to DST it's a judgement call, and IMO it's not necessarily the wrong call either for offset: "reject"
to be as restrictive as possible.
At this point in the proposal where we're very close to Stage 4, I think the bar is quite high to consider this a spec bug. We'd need to have another reason to consider a normative change to this behavior.
One more thing: because the requested change is making an exception case into a non-throwing case, if the current behavior proves to be wrong then it can likely be changed in a follow-up proposal without breaking apps. Which is another reason that we probably shouldn't change this behavior now! :-)
(This is another issue where I'm asking a question to help aide my own understanding.)
Given this code snippet:
I get this exception:
Similarly, for this code snippet (the only change from above is the offset):
I get this exception:
Walking through this, I think the reason why these both throw is that the offset in the input wouldn't match the offset in the
ZonedDateTime
returned. Namely, I believe that2024-03-10T02:30-04:00[America/New_York]
unambiguously refers to2024-03-10T06:30Z
and2024-03-10T02:30-05:00[America/New_York]
unambiguously refers to2024-03-10T07:30Z
. In the former case, the correct zoned instant is actually2024-03-10T01:30-05:00[America/New_York]
, and in the latter case, it's2024-03-10T03:30-04:00[America/New_York]
. As you can see, the offset flip flops. I think that is true for every gap. So I think that in turn means thatoffset: reject
always throws for any datetime in a gap, even if it has a correct offset that disambiguates it.I guess my question here is, is this behavior intended? And if so, what is the rationale behind it? That is, is it preventing the caller from making a mistake somehow? My understanding is that if the offset makes the datetime unambiguous (as I believe it does in this case), then the offset is "valid" and maybe shouldn't result in an error. On the other hand, if
offset: reject
is just about whether the offset in the input matches the offset in the output precisely, then I think the exception is warranted. I'm just having trouble understanding what would go wrong if the datetimes above were parsed without error.