Skip to content
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

Some adjustment rules are ambiguous in TimeZoneInfo.GetSystemTimeZones on unix #11421

Closed
EgorBo opened this issue Nov 6, 2018 · 4 comments
Closed
Labels
area-System.DateTime bug untriaged New issue has not been triaged by the area owner
Milestone

Comments

@EgorBo
Copy link
Member

EgorBo commented Nov 6, 2018

Run the following code snippet on macOS:

foreach (var tmz in TimeZoneInfo.GetSystemTimeZones())
    var tmzClone = TimeZoneInfo.FromSerializedString(tmz.ToSerializedString ());

Expected:
no exceptions (just like on Windows).

Actual:

Unhandled Exception: System.Runtime.Serialization.SerializationException: An error occurred while deserializing the object.  The serialized data is corrupt. ---> System.InvalidTimeZoneException: The elements of the AdjustmentRule array must be in chronological order and must not overlap.
   at System.TimeZoneInfo.ValidateTimeZoneInfo(String id, TimeSpan baseUtcOffset, AdjustmentRule[] adjustmentRules, Boolean& adjustmentRulesSupportDst)
   at System.TimeZoneInfo..ctor(String id, TimeSpan baseUtcOffset, String displayName, String standardDisplayName, String daylightDisplayName, AdjustmentRule[] adjustmentRules, Boolean disableDaylightSavingTime)
   at System.TimeZoneInfo.StringSerializer.GetDeserializedTimeZoneInfo(String source)
   --- End of inner exception stack trace ---
   at System.TimeZoneInfo.StringSerializer.GetDeserializedTimeZoneInfo(String source)

The problem is - some (well, almost all of them) adjustment rules are overlapped, run this to find out which ones:

foreach (var tmz in TimeZoneInfo.GetSystemTimeZones())
{
    var rules = tmz.GetAdjustmentRules();
    var prev = rules.First();
    foreach (var current in rules.Skip(1))
    {
        if (current.DateStart <= prev.DateEnd)	
            Console.WriteLine($"ERR: {tmz.Id}, CurrentStart={current.DateStart}, PrevEnd={prev.DateEnd}");
        prev = current;
    }
}

so the first snippet crashes here: https://github.com/dotnet/coreclr/blob/030a3ea9b8dbeae89c90d34441d4d9a1cf4a7de6/src/System.Private.CoreLib/shared/System/TimeZoneInfo.cs#L1974-L1978

Possible fixes:

  1. Change <= to <
  2. Add a minute/second/tick to all "StartDate"
@RussKeldorph
Copy link
Contributor

@tarekgh

@tarekgh
Copy link
Member

tarekgh commented Jan 16, 2019

@EgorBo yes we are aware of some limitation of the serialization functionality/Adjustment rules on Linux. I am wondering in what scenario you are trying to serialize and de-serialize the time zones? I would say the best practice is to serialize the time zone Id only and use this Id to reconstruct the time zone object again.

@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@maryamariyan maryamariyan added the untriaged New issue has not been triaged by the area owner label Feb 26, 2020
@joperezr
Copy link
Member

joperezr commented Jul 2, 2020

Given @tarekgh's suggestion above and the lack of activity here I'll go ahead and close this one for now. If the suggestion doesn't work or you disagree feel free to reopen.

@joperezr joperezr closed this as completed Jul 2, 2020
@tarekgh
Copy link
Member

tarekgh commented Jul 2, 2020

This is a duplicate of #19794 anyway.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.DateTime bug untriaged New issue has not been triaged by the area owner
Projects
None yet
Development

No branches or pull requests

7 participants