Skip to content

Instantly share code, notes, and snippets.

@lennybacon
Created May 26, 2020 20:40
Show Gist options
  • Select an option

  • Save lennybacon/c31fbed9198451e11aee5b874c450a89 to your computer and use it in GitHub Desktop.

Select an option

Save lennybacon/c31fbed9198451e11aee5b874c450a89 to your computer and use it in GitHub Desktop.

Revisions

  1. lennybacon created this gist May 26, 2020.
    156 changes: 156 additions & 0 deletions TimeZoneInfoConverter.tt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,156 @@
    <#@ template debug="false" hostspecific="true" language="C#" #>
    <#@ output extension=".g.cs" #>
    <#@ assembly name="EnvDTE" #>
    <#@ assembly name="System.Text.Json" #>
    <#@ assembly name="System.Memory" #>
    <#@ assembly name="netstandard" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Net" #>
    <#@ import namespace="System.Text.Json" #>
    <#
    var unicodeDownloadUrl =
    "https://raw.githubusercontent.com/unicode-cldr/cldr-core/master/supplemental/"
    + "windowsZones.json";

    string json;
    using (var client = new WebClient())
    {
    json = client.DownloadString(unicodeDownloadUrl);
    }

    var jsonDoc = JsonDocument.Parse(json);

    var rootElement = jsonDoc.RootElement;
    var supplemental = rootElement.GetProperty("supplemental");
    var windowsZones = supplemental.GetProperty("windowsZones");
    var mapTimezones = windowsZones.GetProperty("mapTimezones");

    #>
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using cyontec.Annotations;

    namespace lennybacon.Globalization {
    /// <summary>
    /// Converts timezones between IANA and windows format.
    /// </summary>
    public class TimeZoneInfoConverter{
    #region _ianaToWindowsTimeZones
    [NotNull]
    private static readonly List<KeyValuePair<string, string>> _s_ianaToWinTz =
    new List<KeyValuePair<string, string>> {
    <#
    foreach(var item in mapTimezones.EnumerateArray()){
    var mapZone = item.GetProperty("mapZone");
    var ianaTimeZones = mapZone.GetProperty("_type").GetString().Split(' ');
    var windowsTimeZone = mapZone.GetProperty("_other").GetString();
    foreach(var ianaTimeZone in ianaTimeZones){
    #>
    new KeyValuePair<string, string>(
    "<#=ianaTimeZone.Replace("_", " ")#>",
    "<#=windowsTimeZone#>"
    ),
    <#
    }
    }
    #>
    };
    #endregion


    /// <summary>
    /// Gets the IANA time zones.
    /// </summary>
    /// <returns>IEnumerable{System.String}.</returns>
    [UsedImplicitly]
    [NotNull]
    public static IEnumerable<string> GetIanaTimeZones() {
    return _s_ianaToWinTz.Select(kvp => kvp.Key);
    }

    /// <summary>
    /// Gets the IANA time zones by windows time zone.
    /// </summary>
    /// <param name="windowsTimeZone">The windows time zone.</param>
    /// <returns>IEnumerable{System.String}.</returns>
    [UsedImplicitly]
    [NotNull]
    public static IEnumerable<string> GetIanaTimeZones(TimeZoneInfo windowsTimeZone) {
    if (windowsTimeZone?.Id == null) {
    throw new ArgumentNullException(nameof(windowsTimeZone));
    }

    return GetIanaTimeZones(windowsTimeZone.Id);
    }

    /// <summary>
    /// Gets the IANA time zone by windows time zone id.
    /// </summary>
    /// <param name="windowsTimeZoneId">
    /// The windows time zone unique
    /// identifier.
    /// </param>
    /// <returns>IEnumerable{System.String}.</returns>
    [UsedImplicitly]
    [NotNull]
    public static IEnumerable<string> GetIanaTimeZones(string windowsTimeZoneId) {
    if (windowsTimeZoneId == null) {
    throw new ArgumentNullException(nameof(windowsTimeZoneId));
    }

    return _s_ianaToWinTz
    .Where(
    tz => string.Equals(tz.Value, windowsTimeZoneId, StringComparison.Ordinal))
    .Select(tz => tz.Key);
    }

    /// <summary>
    /// Gets the window time zone unique identifiers.
    /// </summary>
    /// <returns>IEnumerable{System.String}.</returns>
    [UsedImplicitly]
    [NotNull]
    public static IEnumerable<string> GetWindowTimeZoneIds() {
    return TimeZoneInfo.GetSystemTimeZones()
    .Where(tz => tz != null)
    .Select(tz => tz.Id);
    }

    /// <summary>
    /// Gets the window time zone unique identifiers by IANA time zone info.
    /// </summary>
    /// <param name="ianaTimeZone">The IANA time zone.</param>
    /// <returns>IEnumerable{System.String}.</returns>
    [UsedImplicitly]
    [NotNull]
    public static IEnumerable<string> GetWindowTimeZoneIds(string ianaTimeZone) {
    return _s_ianaToWinTz
    .Where(tz => string.Equals(tz.Key, ianaTimeZone, StringComparison.Ordinal))
    .Select(tz => tz.Value);
    }

    /// <summary>
    /// Gets the window time zone information by IANA time zone info.
    /// </summary>
    /// <param name="ianaTimeZone">The IANA time zone.</param>
    /// <returns>IEnumerable{TimeZoneInfo}.</returns>
    [UsedImplicitly]
    [NotNull]
    public static IEnumerable<TimeZoneInfo> GetWindowTimeZoneInfos(string ianaTimeZone) {
    return GetWindowTimeZoneIds(ianaTimeZone)
    .Select(TimeZoneInfo.FindSystemTimeZoneById);
    }


    /// <summary>
    /// Gets the window time zone information.
    /// </summary>
    /// <returns>IEnumerable{TimeZoneInfo}.</returns>
    [UsedImplicitly]
    [NotNull]
    public static IEnumerable<TimeZoneInfo> GetWindowTimeZoneInfos() {
    return TimeZoneInfo.GetSystemTimeZones();
    }
    }
    }