Skip to content

fix(hook): say the session zone has no DST so the JVM builds it from the offset - #48

Merged
donislawdev merged 1 commit into
mainfrom
fix/java-session-zone
Sep 23, 2026
Merged

donislawdev merged 1 commit into
mainfrom
fix/java-session-zone

Conversation

@donislawdev

@donislawdev donislawdev commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

What was wrong

A Java application under a session read the session date but showed it in the machine's own time zone, on every Java version from 8 on and on both 32 and 64 bit, while the verdict said works. The support matrix called it a known gap and blamed the JVM caching its zone.

The real cause is one field. The JVM (TimeZone_md.c, the same logic in the 8u, 11u, 17u and current lines) calls GetDynamicTimeZoneInformation. With a key name present and DynamicDaylightTimeDisabled set, it builds the zone from Bias. With the field clear, it looks the key name up in its own mapping table, misses "Chrono Session", and reads ActiveTimeBias from the real registry. The hook left the field at its default, FALSE.

The change

h_gdtzi sets DynamicDaylightTimeDisabled = TRUE. MS Learn describes a zone without daylight saving time as this field set with both transition dates cleared, which is exactly the shape of the session zone, so this is the truthful answer rather than a workaround. No new channel, no change to the protocol or the shared control block.

Who else reads the field (checked in their sources)

Runtime Effect
JVM 8 to current builds the session zone from the offset, named GMT+05:30, GMT-03:00, GMT
ICU (Node.js, Deno) same offset as before, a whole-hour zone is now named Etc/GMT-5 (and UTC at +00:00) instead of having no name. A half-hour zone keeps its old path
.NET and .NET Framework unchanged. The field only feeds a registry lookup of "Chrono Session" that fails either way, and the fallback computes its own value
C runtime, Go unchanged. They call GetTimeZoneInformation, which has no such field

Measured before and after

Session zones +05:00, +05:30, -03:00 and +00:00 on a host at +02:00:

Runtime Before After
Java 26 x64, Java 8 x64, Java 8 x86 host offset in every zone session offset in every zone
Node.js, Deno session offset session offset
.NET NativeAOT, Python session offset session offset

Guards, each with its revert probe measured (field set back to FALSE)

  • crates/cli/tests/session_zone.rs (CI): Windows PowerShell reads the field through kernel32 under a +05:30 session, with a control run without one. Reverted, it fails on the field assertion while the two reach assertions (key name, bias -330) still pass.
  • Local harness S13, new run at +05:30: Java reports GMT+05:30 and offset +05:30. Reverted, 8 of 10 on x64 and 8 of 10 on x86, exactly the two zone assertions red.
  • Local support matrix test: the Java note now says the zone is covered, and the check rejects the old note.

Not a regression, noted while measuring

A command-line tool that ships with Windows and prints the current zone key fails under a session with the old value too. It looks the key name up in the registry, which is the "a target that insists on a registry name will not find one" case the README already states. It was considered as the CI target and dropped for that reason.

Not measured

Qt QTimeZone, Chromium with the native hook, and an application that sets its own -Duser.timezone.

Gates

tools/gates.ps1 -Env ran once: 14 of 15, harness 202/202 on x64 and on x86 (S13 grew from 7 to 10 assertions), test-cs 627. The one red gate was test-rust on the network register, which requires a reason for every process a test starts and had none yet for the new test. With the entry added, test-rust passes 528 tests and clippy is clean.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Java now recognizes the session time zone as a fixed offset, such as GMT+05:30. Node.js and Deno use clearer names for whole-hour offsets, including UTC for zero offset.
    • Improved handling of Windows dynamic time-zone information, sped-up timers, and system-object waits.
    • Fixed issues affecting network-connection auditing, .NET timer cautions, and dynamic clock and time-zone coverage in C/C++ runtimes.
  • Documentation
    • Updated the README and time-zone guidance to reflect Java’s session time-zone support.

…the offset

The dynamic zone the hook hands out left DynamicDaylightTimeDisabled at
FALSE. The JVM (TimeZone_md.c, every line from 8 on) then looks the key
name "Chrono Session" up in its own mapping table, misses, and reads
ActiveTimeBias from the real registry, so every Java application under a
session showed the machine's zone while the verdict said works.

MS Learn describes a zone without daylight saving time as this field set
with both transition dates cleared, which is exactly the session zone.
With it set the JVM builds the zone from Bias (GMT+05:30), and ICU names
a whole-hour offset Etc/GMT-N instead of leaving it unnamed. .NET, the C
runtime and Go do not read the field, checked in their sources and by
the harness.

Guard: crates/cli/tests/session_zone.rs reads the field through kernel32
from Windows PowerShell under a session, with a control run without one.
With the field reverted it fails on that assertion and on no other.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 148a5515-3498-477a-a597-82564a1cb06f

📥 Commits

Reviewing files that changed from the base of the PR and between 59306c0 and 6c4ad81.

📒 Files selected for processing (9)
  • CHANGELOG.md
  • README.md
  • crates/cli/tests/network.rs
  • crates/cli/tests/session_zone.rs
  • crates/hook/src/lib.rs
  • site/pages/faq/en.html
  • site/pages/faq/pl.html
  • site/pages/timezone-testing/en.html
  • site/pages/timezone-testing/pl.html

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (6)
  • GitHub Check: submit-nuget
  • GitHub Check: Gates
  • GitHub Check: Semgrep
  • GitHub Check: Analyse actions
  • GitHub Check: Analyse rust
  • GitHub Check: Analyse csharp
🧰 Additional context used
📓 Path-based instructions (12)
Applies to text shown to the user (labels, buttons, tooltips, placeholders, dialogs, errors, status messages, empty states, translations).

⚙️ CodeRabbit configuration file

Files:

  • crates/hook/src/lib.rs
  • crates/cli/tests/network.rs
  • crates/cli/tests/session_zone.rs
Verify tests check real behavior and would fail if the implementation were broken.

⚙️ CodeRabbit configuration file

Files:

  • crates/cli/tests/network.rs
  • crates/cli/tests/session_zone.rs
Performance is a known weak spot of these projects.

⚙️ CodeRabbit configuration file

Files:

  • crates/hook/src/lib.rs
  • crates/cli/tests/network.rs
  • crates/cli/tests/session_zone.rs
Applies only to code that builds or styles a GUI.

⚙️ CodeRabbit configuration file

Files:

  • crates/hook/src/lib.rs
  • crates/cli/tests/network.rs
  • crates/cli/tests/session_zone.rs
User-facing changelog.

⚙️ CodeRabbit configuration file

Files:

  • CHANGELOG.md
SECURITY, HIGH PRIORITY.

⚙️ CodeRabbit configuration file

Files:

  • crates/hook/src/lib.rs
  • crates/cli/tests/network.rs
  • crates/cli/tests/session_zone.rs
Source of the public project website (generated output is excluded from review).

⚙️ CodeRabbit configuration file

Files:

  • site/pages/faq/pl.html
  • site/pages/faq/en.html
  • site/pages/timezone-testing/pl.html
  • site/pages/timezone-testing/en.html
Check that documentation matches the actual code in this PR: commands, flags, config keys, file paths, build steps and examples must exist.

⚙️ CodeRabbit configuration file

Files:

  • CHANGELOG.md
  • README.md
Rust code.

⚙️ CodeRabbit configuration file

Files:

  • crates/hook/src/lib.rs
  • crates/cli/tests/network.rs
  • crates/cli/tests/session_zone.rs
All code in this repository is written by an AI coding agent (Claude Code).

⚙️ CodeRabbit configuration file

Files:

  • site/pages/faq/pl.html
  • site/pages/faq/en.html
  • site/pages/timezone-testing/pl.html
  • crates/hook/src/lib.rs
  • crates/cli/tests/network.rs
  • CHANGELOG.md
  • site/pages/timezone-testing/en.html
  • README.md
  • crates/cli/tests/session_zone.rs
Source excerpt: **Everything inside the repository is English**, including comments.

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Files:

  • site/pages/faq/pl.html
  • site/pages/faq/en.html
  • site/pages/timezone-testing/pl.html
  • crates/hook/src/lib.rs
  • crates/cli/tests/network.rs
  • CHANGELOG.md
  • site/pages/timezone-testing/en.html
  • README.md
  • crates/cli/tests/session_zone.rs
Scope, duplication and docs: Warn if any of these is true: the PR contains significant changes not mentioned in the title/description, or mixes unrelated refactors with a feature or fix; the PR adds functionality, helpers, UI components, st...

📄 CodeRabbit inference engine (Custom checks)

Files:

  • CHANGELOG.md
  • README.md

📝 Walkthrough

Walkthrough

The dynamic time-zone hook now disables daylight saving time. A Windows integration test checks the session zone key, bias, and daylight-disable field. Documentation describes Java’s fixed-offset zone name and offset-based names for other runtimes.

Changes

Session time-zone reporting

Layer / File(s) Summary
Dynamic time-zone response and Windows test
crates/hook/src/lib.rs, crates/cli/tests/session_zone.rs, crates/cli/tests/network.rs
The dynamic time-zone response sets DynamicDaylightTimeDisabled to true. The Windows test checks the control and session probes, including the session key, -330 bias, and daylight-disable field. The network test register allows the new test to spawn processes.
Session time-zone documentation
README.md, site/pages/faq/*.html, site/pages/timezone-testing/*.html, CHANGELOG.md
The README and site pages describe Java’s session zone as a fixed offset, such as GMT+05:30. They also describe offset-based names for other runtimes. The changelog lists these naming details and other fixes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: bug

Merge Risk: ⚪ Minimal · up to 6c4ad

The session time-zone change has no identified issue requiring a fix before merge; normal checks remain appropriate.

🚥 Pre-merge checks | ✅ 12 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Clear User-Facing Text ⚠️ Warning The PR changes user-facing documentation but uses multiple names for the same concepts. The new changelog calls the same host zone “the machine's time zone” and “the machine's own time zone,” while th… Standardize the new prose on one term for each concept. Use “session time zone” instead of “session zone,” and use one host-zone term, such as “machine time zone,” instead of both “machine's time zone” and “machine's own time zone.” Apply t…
No Resource Leaks ⚠️ Warning The new crates/cli/tests/session_zone.rs test leaks its temporary scratch directories on failure paths. scratch("control") and scratch("session") create directories containing zone.ps1 and pro… Add an RAII cleanup guard for each scratch directory, with Drop calling remove_dir_all, or otherwise place cleanup in an unconditional guard. Ensure both the control directory and the session directory are removed when process execution…
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main code change: disabling daylight saving time for the session zone so the JVM uses the session offset. It is specific and within the 140-character limit.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Tests For Changed Behavior ✅ Passed The PR changes runtime behavior in h_gdtzi by setting DynamicDaylightTimeDisabled: true. It adds crates/cli/tests/session_zone.rs, which runs a control and session probe through `GetDynamicTimeZ…
No Secrets Or Debug Leftovers ✅ Passed The reviewed diff adds no CLAUDE.md, AGENTS.md, .claude/, or .env file. Focused scans of added lines found no credentials, tokens, private URLs, user-specific paths, personal emails, or debug-output c…
No Hardcoded Ui Styling ✅ Passed The pull request does not add or change GUI code. The authoritative diff contains Markdown, documentation HTML, and Rust hook/test files only. The HTML changes update documentation text and do not add…
No Obvious Performance Problems ✅ Passed No clear performance problem is introduced. The production change only sets one field in h_gdtzi and performs no loop, polling, collection processing, UI work, or repeated I/O. The new test starts P…
Desktop Robustness ✅ Passed PASS. The PR changes the Windows time-zone hook, documentation, and a Windows integration test. The new test writes only temporary probe files, runs a short PowerShell probe, and performs no network c…
Safe File Parsing ✅ Passed PASS — The PR does not add XML, XAML, CSV, XLSX, JSON, YAML, translation, theme, settings, or archive parsing. The new test reads only its own bounded plain-text zone.txt with `std::fs::read_to_stri…
System Changes Are Reversible ✅ Passed PASS: The PR does not introduce a persistent system-state change. The only product-code change sets DynamicDaylightTimeDisabled: true in the already existing h_gdtzi process-hook response. It does…
Scope, Duplication And Docs ✅ Passed The PR has a single coherent scope: report the session zone as fixed-offset/no-DST and verify it. The changed hook field, Windows integration test, network-test allowance, README, CHANGELOG, FAQ, and …
Full details: Clear User-Facing Text

Explanation

The PR changes user-facing documentation but uses multiple names for the same concepts. The new changelog calls the same host zone “the machine's time zone” and “the machine's own time zone,” while the documentation alternates between “session time zone” and “session zone.” This violates the check's terminology-consistency condition.

Resolution

Standardize the new prose on one term for each concept. Use “session time zone” instead of “session zone,” and use one host-zone term, such as “machine time zone,” instead of both “machine's time zone” and “machine's own time zone.” Apply the terms consistently in CHANGELOG.md, README.md, and the English and Polish site pages.

Full details: No Resource Leaks

Explanation

The new crates/cli/tests/session_zone.rs test leaks its temporary scratch directories on failure paths. scratch("control") and scratch("session") create directories containing zone.ps1 and probe output, but remove_dir_all runs only after later assertions succeed. A failed process start, non-success status, malformed output, or failed zone assertion panics before cleanup. This can leave chrono-session-zone-* files in the system temporary directory. The launched processes are waited on by status()/output() and are not the leak.

Resolution

Add an RAII cleanup guard for each scratch directory, with Drop calling remove_dir_all, or otherwise place cleanup in an unconditional guard. Ensure both the control directory and the session directory are removed when process execution or any assertion fails.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
✨ Simplify code
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the bug Something isn't working label Sep 23, 2026
@donislawdev
donislawdev merged commit d349e8f into main Sep 23, 2026
9 checks passed
@donislawdev
donislawdev deleted the fix/java-session-zone branch September 23, 2026 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant