Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull Request Overview
This PR implements a comprehensive performance improvement to .NET's time zone handling system by introducing a per-year caching mechanism for time zone transitions. The change aims to address significant performance issues, particularly on Linux, when converting times across different time zones and during DateTime.Now operations.
Key changes:
- Introduces per-year caching of time zone transitions to eliminate repeated rule lookups
- Replaces complex rule-based conversion logic with simplified cache-backed helper methods
- Streamlines DateTime.Now implementation using optimized caching for better performance
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| System/TimeZoneInfo.Cache.cs | New file implementing the core caching mechanism for time zone transitions |
| System/TimeZoneInfo.cs | Major refactoring to use cache-based conversion methods instead of rule-based logic |
| System/TimeZoneInfo.Win32.cs | Cleanup of Windows-specific DateTime.Now optimization code |
| System/TimeZoneInfo.Unix.cs | Cleanup of Unix-specific DateTime.Now optimization code |
| System/DateTime.cs | Simplified DateTime.Now implementation using new caching system |
| System.Private.CoreLib.Shared.projitems | Added new cache file to build system |
| System/TimeZoneInfoTests.cs | Added comprehensive test cases for invalid and ambiguous time detection |
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
This was referenced Sep 12, 2025
b9d505d to
2c482cc
Compare
lilinus
reviewed
Sep 17, 2025
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs
Outdated
Show resolved
Hide resolved
jozkee
reviewed
Sep 18, 2025
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
jozkee
reviewed
Sep 26, 2025
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
jozkee
approved these changes
Oct 3, 2025
Member
jozkee
left a comment
There was a problem hiding this comment.
Functionally, looks got to me; it is quite complex though, left a few comments to improve readability.
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
This was referenced Oct 5, 2025
This was referenced Oct 28, 2025
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change aims to improve time zone handling in .NET.
Current Issues
Performance problems: Multiple reports highlight performance concerns when converting times across different time zones—especially between local and UTC. The performance degradation is even more noticeable on Linux. More details are included below. Examples of reported issues: #24839, #24277, #25075.
Correctness and reliability: Users occasionally report incorrect results when working with time zones. A major contributing factor is that the time zone handling code was originally written long ago and has since been patched many times. These incremental fixes have made the implementation difficult to maintain, and it’s often unclear whether a new fix might cause regressions elsewhere. While we have fair to good test coverage, it cannot guarantee correctness across all possible time conversion scenarios and supported time zones. Examples of reported issues: #118915, #114476.
How Time Zones Work Today
When converting time between time zones, .NET primarily relies on the base UTC offset (e.g., -8:00 hours for Pacific Standard Time) along with historical and future transition data for each zone. These transitions are expressed through AdjustmentRules, where each rule covers one or more years.
An AdjustmentRule specifies:
Data sources
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones.tzdatapackage, which contains the IANA database. IANA data is much more comprehensive, including detailed historical records for every time zone. This means Linux typically has far more rules per time zone than Windows.Rule types
Another difference: Windows stores transition times in local time, while Linux stores them in UTC. Since the sources differ, .NET does not normalize this when reading the data.
Conversion process
When converting time between zones, .NET:
Checks whether the zone supports daylight saving time.
Locates the appropriate rule for the target year.
Applies the rule to perform the conversion.
Summary
The conversion process involves significant computation, especially on Linux, where the number of rules per time zone is much higher.
The Change
We are introducing a per-year cache to store time zone transitions. This cache is created on-demand—only when a given year is accessed—and contains all possible transitions for that year.
Each cache entry includes:
With this approach, time conversion requires only a single cache lookup, without repeatedly consulting the underlying rules. The cache mapping is stored in a concurrent dictionary, allowing efficient thread-safe access.
Benefits
DateTime.Kind.In other words, rules are used only when building a new cache entry; once cached, all conversions run through the simplified lookup path.
Note: In typical scenarios, users work with only a small range of years for time conversions, so the cache should not pose any issues. For extreme cases, developers can clear the cache using
TimeZoneInfo.ClearCachedData.Testing
DateTime.Now.Performance results
Windows
Linux (WSL)
Opportunities
This change opens the door to several improvements:
DateTimeOffsetinstead ofDateTimefor time zone scenarios, many developers still rely onDateTimeand often run into issues related toDateTime.Kind. A cleaner API surface could help mitigate these problems.Fixes #24839, #24277, #25075, #118915, #114476