Skip to content

fix(ext/os): respect TZ environment variable on Windows (WIP)#34705

Draft
bartlomieju wants to merge 1 commit into
mainfrom
fix/windows-tz-env
Draft

fix(ext/os): respect TZ environment variable on Windows (WIP)#34705
bartlomieju wants to merge 1 commit into
mainfrom
fix/windows-tz-env

Conversation

@bartlomieju

Copy link
Copy Markdown
Member

WIP / draft — depends on denoland/rusty_v8#2000 (adds
v8::icu::set_default_time_zone) and a subsequent v8 crate bump. The
Windows code paths are #[cfg(windows)]-gated, so Linux/macOS builds and
the new spec test pass today; the Windows build stays red until the v8
bump lands.

Fixes #15370.

V8 derives its Date time zone from ICU. On unix ICU reads the TZ
environment variable, but on Windows ICU detects the host time zone from
the OS and ignores TZ. So $env:TZ='UTC'; deno run ... (and even
Deno.env.set("TZ", ...)) had no effect on Windows, while Node honors it
on every platform.

This applies TZ to ICU explicitly on Windows (matching Node's
SetDefaultTimeZone):

  • startup: after init_platform, install TZ from the environment in
    both the CLI (cli/lib.rs) and the compiled-binary / denort entry point
    (cli/rt/run.rs), before any isolate uses Date;
  • runtime set: in op_set_env's dt_change_notif, set the zone and
    notify the isolate with TimeZoneDetection::Skip so cached values
    refresh without re-detecting (and overwriting) what we just set;
  • runtime delete: op_delete_env now refreshes the zone too — it
    previously didn't call dt_change_notif at all, so unsetting TZ never
    took effect.

Unix keeps the existing tzset + Redetect path, which also handles
non-IANA TZ formats (e.g. POSIX PST8PDT).

Adds tests/specs/run/tz_env, which runs on all platforms and would have
caught the Windows regression.

TODO before un-drafting:

  • land rusty_v8#2000, bump the v8 crate, drop the WIP note;
  • consider whether the unix non-IANA TZ edge cases warrant applying the
    explicit path on all platforms instead of Windows-only.

V8 derives its Date time zone from ICU. On unix ICU reads the TZ
environment variable, but on Windows ICU detects the host time zone from
the OS and ignores TZ, so a TZ set before launch (or via Deno.env.set)
had no effect there (#15370).

Apply TZ to ICU explicitly on Windows via the new
v8::icu::set_default_time_zone, matching Node:

- at startup (after init_platform) for TZ set in the environment, in both
  the CLI and the compiled-binary (denort) entry points;
- in op_set_env's dt_change_notif when TZ is set at runtime, notifying the
  isolate with TimeZoneDetection::Skip so caches refresh without
  re-detecting (and overwriting) the zone just set;
- in op_delete_env, which previously didn't refresh the zone at all.

Unix keeps the existing tzset + Redetect path, which also handles
non-IANA TZ formats.

WIP: depends on denoland/rusty_v8#2000 and a v8 crate bump; the Windows
code paths won't compile until that lands. Adds a tests/specs/run/tz_env
regression test that runs on all platforms.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TZ environment variable not respected in PowerShell

1 participant