Open clement911 opened 1 year ago
The (most likely relevant) official North Korean time zone change was from +0900 to +0830 on 2015-08-15, and from +0830 to +0900 on 2018-05-04 (both times giving less than two weeks notification of the change). So the observed behavior is really wrong.
The utc offset shouldn't change twice within the span of hour
While this specific instance is a bug of some sort, UTC offsets are decided by national governments. Changing the offset multiple times in an hour is a valid (if confusing) thing to do.
There's also nothing "special" about an hour in relation to UTC offsets, other than the fact that most offsets (and DST, when applicable) are in hour increments. Some offsets are +30min, as was the case here. There are some that use +45min. And there is/was a zone that used a +30min DST change.
@Clockwork-Muse
Changing the offset multiple times in an hour is a valid (if confusing) thing to do.
Ok, so maybe it's technically valid and I didn't describe the root problem correctly, but there is a bug nonetheless.
We found several more timezones that exhibit a similar behaviour. That is, they change the UTC offset at one moment, and then revert it 1 hour later. It always happens on December 31st, which I find very suspicious.
See the following script showing 4 more occurrences, but there are a few more exhibiting the same weird behaviour.
string tzName = "Sao Tome Standard Time";
var utc = DateTimeOffset.Parse("2018-12-31T23:00:00Z");
var tz = TimeZoneInfo.FindSystemTimeZoneById(tzName);
Console.WriteLine(TimeZoneInfo.ConvertTime(utc, tz));
Console.WriteLine(TimeZoneInfo.ConvertTime(utc.AddMinutes(60), tz));
Console.WriteLine(TimeZoneInfo.ConvertTime(utc.AddMinutes(120), tz));
Console.WriteLine();
tzName = "Altai Standard Time";
utc = DateTimeOffset.Parse("2013-12-31T16:00:00Z");
tz = TimeZoneInfo.FindSystemTimeZoneById(tzName);
Console.WriteLine(TimeZoneInfo.ConvertTime(utc, tz));
Console.WriteLine(TimeZoneInfo.ConvertTime(utc.AddMinutes(60), tz));
Console.WriteLine(TimeZoneInfo.ConvertTime(utc.AddMinutes(120), tz));
Console.WriteLine();
tzName = "Saratov Standard Time";
utc = DateTimeOffset.Parse("2013-12-31T19:00:00Z");
tz = TimeZoneInfo.FindSystemTimeZoneById(tzName);
Console.WriteLine(TimeZoneInfo.ConvertTime(utc, tz));
Console.WriteLine(TimeZoneInfo.ConvertTime(utc.AddMinutes(60), tz));
Console.WriteLine(TimeZoneInfo.ConvertTime(utc.AddMinutes(120), tz));
Console.WriteLine();
tzName = "Volgograd Standard Time";
utc = DateTimeOffset.Parse("2018-12-31T19:00:00Z");
tz = TimeZoneInfo.FindSystemTimeZoneById(tzName);
Console.WriteLine(TimeZoneInfo.ConvertTime(utc, tz));
Console.WriteLine(TimeZoneInfo.ConvertTime(utc.AddMinutes(60), tz));
Console.WriteLine(TimeZoneInfo.ConvertTime(utc.AddMinutes(120), tz));
Console.WriteLine();
Console.Read();
Output!
31/12/2018 11:00:00 PM +00:00
1/01/2019 1:00:00 AM +01:00
1/01/2019 1:00:00 AM +00:00
31/12/2013 11:00:00 PM +07:00
31/12/2013 11:00:00 PM +06:00
1/01/2014 1:00:00 AM +07:00
31/12/2013 11:00:00 PM +04:00
31/12/2013 11:00:00 PM +03:00
1/01/2014 1:00:00 AM +04:00
31/12/2018 11:00:00 PM +04:00
31/12/2018 11:00:00 PM +03:00
1/01/2019 1:00:00 AM +04:00
Agreed that there's some sort of bug. This seems to be a Windows-only issue, so is either something in the base data or their specific format (Windows is.... special here).
My initial first guess would be that it's mishandling cases where the base offset for the timezone changes at some point during the year, and no DST, given that seems to be happening for those years for those timezones. I believe the Windows data format and/or TimeZoneInfo
may have some holes in this area.
FWIW I see the same behavior on .NETCore 3.1 and 6.0, so this doesn't appear to be a regression.
C:\scratch\timeZone>C:\scratch\timeZone\bin\Debug\netcoreapp3.1\timeZone.exe
12/31/2014 11:30:00 PM +09:00
12/31/2014 11:30:00 PM +08:30
1/1/2015 12:30:00 AM +09:00
C:\scratch\timeZone>C:\scratch\timeZone\bin\Debug\net6.0\timeZone.exe
12/31/2014 11:30:00 PM +09:00
12/31/2014 11:30:00 PM +08:30
1/1/2015 12:30:00 AM +09:00
C:\scratch\timeZone>C:\scratch\timeZone\bin\Debug\net7.0\timeZone.exe
12/31/2014 11:30:00 PM +09:00
12/31/2014 11:30:00 PM +08:30
1/1/2015 12:30:00 AM +09:00
This seems a bug,
According to the Windows data, we have the following North Korea Standard Time
rule for year 2015
.
DateStart : 01/01/2015 00:00:00 (Unspecified)
DateEnd : 12/31/2015 00:00:00 (Unspecified)
DaylightDelta : 00:30:00
DaylightTransitionStart : M:1, D:1, W:1, DoW:Thursday, Time:01/01/0001 00:00:00, FixedDate:False
DaylightTransitionEnd : M:8, D:1, W:2, DoW:Friday, Time:01/01/0001 23:59:59, FixedDate:False
BaseUtcOffsetDelta : -00:30:00
NoDaylightTransitions : False
The problem is the daylight saving is not detected in the first half hour of the year. Calling tz.IsDaylightSavingTime(utc.AddMinutes(30))
return false while it should be true. This is why you are seeing 30:00 minutes shift in the converted time.
... North Korea doesn't (and didn't) observe DST. This is a base offset change only.
@Clockwork-Muse right but the issue is Windows TZ data cannot describe the base offset change during the year (in August 2015). It seems to me to work around the issue in the data, it created a rule with DST that starts in the beginning of the year and ends in August.
Description
For some timezones, at specific times, the UTC offset behaves illogically.
Reproduction Steps
With .NET 7
Expected behavior
The utc offset shouldn't change twice within the span of hour
Actual behavior
The utc offset changes twice within the span of hour
Output:
Regression?
Not sure
Known Workarounds
No response
Configuration
.NET 7, windows 11
Other information
No response