-
Notifications
You must be signed in to change notification settings - Fork 5.2k
TimeZones improvement #119662
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
TimeZones improvement #119662
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
b9d505d
to
2c482cc
Compare
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.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
src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.Cache.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functionally, looks got to me; it is quite complex though, left a few comments to improve readability.
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
.tzdata
package, 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:
DateTimeOffset
instead ofDateTime
for time zone scenarios, many developers still rely onDateTime
and often run into issues related toDateTime.Kind
. A cleaner API surface could help mitigate these problems.Fixes #24839, #24277, #25075, #118915, #114476