Skip to content

Date local setters use the current-time tz offset instead of the target-date offset (DST off-by-one-hour; TZ-dependent unit test) #4927

@proggeramlug

Description

@proggeramlug

Symptom

cargo test -p perry-runtime --lib date::tests::test_full_year_setters_revive_invalid_date_only fails on any machine whose current UTC offset differs from the offset at the target date, and passes under TZ=UTC:

  • Run in June (CEST, UTC+2): setFullYear(2020) on an Invalid Date revives to a timestamp whose getHours() is 1, not 0 (expected local 2020-01-01T00:00:00, January is CET, UTC+1).
  • TZ=America/New_York fails the same way; TZ=UTC passes — which is why CI (UTC) is green and the bug goes unnoticed.

Root cause (suspected)

The local→UTC conversion in the setter/revive path (rebuild_local_with / the components→timestamp helper in crates/perry-runtime/src/date.rs) applies the timezone offset at the current time rather than the offset at the target instant. Per ECMA-262 LocalTZA(t, false) / MakeDay semantics, the offset must be computed for the time value being constructed (and needs the usual fixed-point iteration around DST transitions, since the offset depends on the result).

getHours() decodes with the offset at the stored instant (correct), so the two disagree by exactly the DST delta whenever the construction-time offset ≠ target-date offset.

Impact

Any local-time Date setter (setFullYear/setMonth/setDate/setHours/…) and likely new Date(y, m, d, …) local construction is off by the DST delta when the target date is on the other side of a DST boundary from "now". Affects real programs, not just the test.

Found while triaging PR #4924 (the test failure reproduces on unmodified main; it is unrelated to that PR's changes).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions