Last active
April 29, 2021 11:57
-
-
Save aidmsu/5f940a9694335a3da1feaecab71ebc8e to your computer and use it in GitHub Desktop.
Find time zones wtih wrong DST time transition info
This file contains 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
using System; | |
using System.Globalization; | |
using System.Linq; | |
using System.Collections.Generic; | |
public class Program | |
{ | |
private static readonly TimeSpan OneSecond = TimeSpan.FromSeconds(1); | |
private static readonly bool _onlyZonesWithActualWrongInfo = true; | |
public static void Main(string[] args) | |
{ | |
var zones = TimeZoneInfo.GetSystemTimeZones(); | |
var wrongDstInfoZones = zones.Where(HasWrongDstInfo).ToList(); | |
Console.WriteLine($"Wrong DST info zones count: {wrongDstInfoZones.Count}. Total: {zones.Count}"); | |
foreach (var zone in wrongDstInfoZones) | |
{ | |
Console.WriteLine("-------------------------------------------------------------------------------------"); | |
var wrongRules = zone.GetAdjustmentRules().Where(IsAdjustmentRuleWrong).ToList(); | |
Console.WriteLine($"{zone.Id}. Wrong rules count: {wrongRules.Count}"); | |
Console.WriteLine(); | |
var rulesCountToDisplay = _onlyZonesWithActualWrongInfo ? 1 : int.MaxValue; | |
foreach (var rule in wrongRules.OrderByDescending(r => r.DateEnd).Take(rulesCountToDisplay)) | |
{ | |
Console.WriteLine($"Rule for ({rule.DateStart:yyyy-MM-dd}, {rule.DateEnd:yyyy-MM-dd}) period. "); | |
if (IsTransitionTimeWrong(rule.DaylightTransitionStart)) | |
{ | |
var transitionStart = rule.DaylightTransitionStart; | |
Console.WriteLine($"\tTransition start: {ToString(transitionStart)}"); | |
} | |
if (IsTransitionTimeWrong(rule.DaylightTransitionEnd)) | |
{ | |
var transitionEnd = rule.DaylightTransitionEnd; | |
Console.WriteLine($"\tTransition end: {ToString(transitionEnd)}."); | |
} | |
} | |
} | |
Console.ReadLine(); | |
} | |
public static bool HasWrongDstInfo(TimeZoneInfo zone) | |
{ | |
IEnumerable<TimeZoneInfo.AdjustmentRule> rules = zone.GetAdjustmentRules(); | |
if (_onlyZonesWithActualWrongInfo) | |
{ | |
var currentYear = DateTime.UtcNow.Year; | |
rules = rules.Where(r => r.DateEnd.Year > currentYear); | |
} | |
return zone.SupportsDaylightSavingTime && rules.Any(IsAdjustmentRuleWrong); | |
} | |
public static bool IsAdjustmentRuleWrong(TimeZoneInfo.AdjustmentRule rule) | |
{ | |
if (rule.DaylightDelta == TimeSpan.Zero) return false; | |
return IsTransitionTimeWrong(rule.DaylightTransitionStart) || IsTransitionTimeWrong(rule.DaylightTransitionEnd); | |
} | |
public static bool IsTransitionTimeWrong(TimeZoneInfo.TransitionTime transitionTime) | |
{ | |
var timeOfDay = transitionTime.TimeOfDay; | |
return timeOfDay.Ticks % OneSecond.Ticks != 0; | |
} | |
public static string ToString(TimeZoneInfo.TransitionTime transitionTime) | |
{ | |
var monthNames = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames; | |
var monthName = monthNames[transitionTime.Month - 1]; | |
var day = transitionTime.Day; | |
var timeOfDay = $"{transitionTime.TimeOfDay:HH:mm:ss.fffffff}"; | |
var week = ((WeekOfMonth)transitionTime.Week).ToString(); | |
return transitionTime.IsFixedDateRule | |
? $"on {monthName} {day} at {timeOfDay}" | |
: $"the {week} {transitionTime.DayOfWeek} of {monthName} at {timeOfDay}"; | |
} | |
private enum WeekOfMonth | |
{ | |
First = 1, | |
Second = 2, | |
Third = 3, | |
Fourth = 4, | |
Last = 5, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment