Skip to content

Instantly share code, notes, and snippets.

@aidmsu
Last active April 29, 2021 11:57
Show Gist options
  • Save aidmsu/5f940a9694335a3da1feaecab71ebc8e to your computer and use it in GitHub Desktop.
Save aidmsu/5f940a9694335a3da1feaecab71ebc8e to your computer and use it in GitHub Desktop.
Find time zones wtih wrong DST time transition info
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