Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

treat all offsets as invalid for gaps in civil time #212

Closed
BurntSushi opened this issue Jan 23, 2025 · 0 comments
Closed

treat all offsets as invalid for gaps in civil time #212

BurntSushi opened this issue Jan 23, 2025 · 0 comments
Labels
breaking change Issues that require a breaking change for resolution. enhancement New feature or request

Comments

@BurntSushi
Copy link
Owner

Jiff currently has this behavior:

use jiff::Zoned;

fn main() -> anyhow::Result<()> {
    let zdt: Zoned = "2024-03-10T02:30-05[US/Eastern]".parse()?;
    assert_eq!(zdt.to_string(), "2024-03-10T03:30:00-04:00[US/Eastern]");
    let zdt: Zoned = "2024-03-10T02:30-04[US/Eastern]".parse()?;
    assert_eq!(zdt.to_string(), "2024-03-10T01:30:00-05:00[US/Eastern]");

    Ok(())
}

However, this does not match Temporal's behavior:

>> Temporal.ZonedDateTime.from("2024-03-10T02:30-05[US/Eastern]").toString()
Uncaught RangeError: Offset -05:00 is invalid for 2024-03-10T02:30:00 in US/Eastern
    InterpretISODateTimeOffset ecmascript.mjs:1467
    ToTemporalZonedDateTime ecmascript.mjs:1531
    from zoneddatetime.mjs:478
    <anonymous> debugger eval code:1
>> Temporal.ZonedDateTime.from("2024-03-10T02:30-04[US/Eastern]").toString()
Uncaught RangeError: Offset -04:00 is invalid for 2024-03-10T02:30:00 in US/Eastern
    InterpretISODateTimeOffset ecmascript.mjs:1467
    ToTemporalZonedDateTime ecmascript.mjs:1531
    from zoneddatetime.mjs:478
    <anonymous> debugger eval code:1
[ecmascript.mjs:1467:10](https://tc39.es/polyfill/lib/ecmascript.mjs)

I believe this was intentional on my part:

jiff/src/tz/offset.rs

Lines 1590 to 1616 in 94e8270

Err(err!(
"datetime {dt} could not resolve to timestamp \
since 'reject' conflict resolution was chosen, and \
because datetime has offset {given}, but the time \
zone {tzname} for the given datetime falls in a gap \
between offsets {before} and {after}, neither of which \
match the offset",
tzname = tz.diagnostic_name(),
))
}
Fold { before, after } if given != before && given != after => {
Err(err!(
"datetime {dt} could not resolve to timestamp \
since 'reject' conflict resolution was chosen, and \
because datetime has offset {given}, but the time \
zone {tzname} for the given datetime falls in a fold \
between offsets {before} and {after}, neither of which \
match the offset",
tzname = tz.diagnostic_name(),
))
}
Gap { .. } | Fold { .. } => {
let kind = Unambiguous { offset: given };
Ok(AmbiguousTimestamp::new(dt, kind).into_ambiguous_zoned(tz))
}
}
}

And indeed, I filed an issue about this here: tc39/proposal-temporal#2892

I find myself agreeing more with Temporal's behavior here. In particular, Temporal returning an error here is meant to catch once-valid-but-no-longer datetime strings because of DST changes. And especially the conservative stance I find appealing: it would be better to return an error here since converting that into a non-error is easier than the reverse.

So for jiff 0.2, I'll plan to turn the cases above into errors.

@BurntSushi BurntSushi added breaking change Issues that require a breaking change for resolution. enhancement New feature or request labels Jan 23, 2025
BurntSushi added a commit that referenced this issue Jan 25, 2025
This will cause Jiff to reject some datetime strings that it
previously accepted. This also brings Jiff into line with how
Temporal behaves in these case. It is overall safe because
it avoids misinterpreting datetimes in the future that are
serialized before a change to DST. For example, imagine serializing
`2006-04-02T02:30-05[America/Indiana/Vevay]` before you knew that
Indiana/Vevay was going to switch to DST (they hadn't previously used
DST since 1972). Before that switch, it was perfectly reasonable to
think that the datetime was valid. But after the switch, it corresponded
to a gap. Jiff will now reject this.

Users can still of course change the offset conflict resolution strategy
depending on what they want to do (reject, keep exact time or keep civil
time).

Fixes #212
BurntSushi added a commit that referenced this issue Jan 25, 2025
This will cause Jiff to reject some datetime strings that it
previously accepted. This also brings Jiff into line with how
Temporal behaves in these case. It is overall safe because
it avoids misinterpreting datetimes in the future that are
serialized before a change to DST. For example, imagine serializing
`2006-04-02T02:30-05[America/Indiana/Vevay]` before you knew that
Indiana/Vevay was going to switch to DST (they hadn't previously used
DST since 1972). Before that switch, it was perfectly reasonable to
think that the datetime was valid. But after the switch, it corresponded
to a gap. Jiff will now reject this.

Users can still of course change the offset conflict resolution strategy
depending on what they want to do (reject, keep exact time or keep civil
time).

Fixes #212
BurntSushi added a commit that referenced this issue Jan 25, 2025
This will cause Jiff to reject some datetime strings that it
previously accepted. This also brings Jiff into line with how
Temporal behaves in these case. It is overall safe because
it avoids misinterpreting datetimes in the future that are
serialized before a change to DST. For example, imagine serializing
`2006-04-02T02:30-05[America/Indiana/Vevay]` before you knew that
Indiana/Vevay was going to switch to DST (they hadn't previously used
DST since 1972). Before that switch, it was perfectly reasonable to
think that the datetime was valid. But after the switch, it corresponded
to a gap. Jiff will now reject this.

Users can still of course change the offset conflict resolution strategy
depending on what they want to do (reject, keep exact time or keep civil
time).

Fixes #212
BurntSushi added a commit that referenced this issue Jan 27, 2025
This will cause Jiff to reject some datetime strings that it
previously accepted. This also brings Jiff into line with how
Temporal behaves in these case. It is overall safe because
it avoids misinterpreting datetimes in the future that are
serialized before a change to DST. For example, imagine serializing
`2006-04-02T02:30-05[America/Indiana/Vevay]` before you knew that
Indiana/Vevay was going to switch to DST (they hadn't previously used
DST since 1972). Before that switch, it was perfectly reasonable to
think that the datetime was valid. But after the switch, it corresponded
to a gap. Jiff will now reject this.

Users can still of course change the offset conflict resolution strategy
depending on what they want to do (reject, keep exact time or keep civil
time).

Fixes #212
BurntSushi added a commit that referenced this issue Jan 30, 2025
This will cause Jiff to reject some datetime strings that it
previously accepted. This also brings Jiff into line with how
Temporal behaves in these case. It is overall safe because
it avoids misinterpreting datetimes in the future that are
serialized before a change to DST. For example, imagine serializing
`2006-04-02T02:30-05[America/Indiana/Vevay]` before you knew that
Indiana/Vevay was going to switch to DST (they hadn't previously used
DST since 1972). Before that switch, it was perfectly reasonable to
think that the datetime was valid. But after the switch, it corresponded
to a gap. Jiff will now reject this.

Users can still of course change the offset conflict resolution strategy
depending on what they want to do (reject, keep exact time or keep civil
time).

Fixes #212
BurntSushi added a commit that referenced this issue Feb 1, 2025
This will cause Jiff to reject some datetime strings that it
previously accepted. This also brings Jiff into line with how
Temporal behaves in these case. It is overall safe because
it avoids misinterpreting datetimes in the future that are
serialized before a change to DST. For example, imagine serializing
`2006-04-02T02:30-05[America/Indiana/Vevay]` before you knew that
Indiana/Vevay was going to switch to DST (they hadn't previously used
DST since 1972). Before that switch, it was perfectly reasonable to
think that the datetime was valid. But after the switch, it corresponded
to a gap. Jiff will now reject this.

Users can still of course change the offset conflict resolution strategy
depending on what they want to do (reject, keep exact time or keep civil
time).

Fixes #212
BurntSushi added a commit that referenced this issue Feb 2, 2025
This will cause Jiff to reject some datetime strings that it
previously accepted. This also brings Jiff into line with how
Temporal behaves in these case. It is overall safe because
it avoids misinterpreting datetimes in the future that are
serialized before a change to DST. For example, imagine serializing
`2006-04-02T02:30-05[America/Indiana/Vevay]` before you knew that
Indiana/Vevay was going to switch to DST (they hadn't previously used
DST since 1972). Before that switch, it was perfectly reasonable to
think that the datetime was valid. But after the switch, it corresponded
to a gap. Jiff will now reject this.

Users can still of course change the offset conflict resolution strategy
depending on what they want to do (reject, keep exact time or keep civil
time).

Fixes #212
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change Issues that require a breaking change for resolution. enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant