What's the Noda Time 2.0 equivalent of MapTimeZoneId?

I have been using the following code without flaw for a while now:

internal static string WindowsToIana(string windowsZoneId)
{
    if (windowsZoneId.Equals("UTC", StringComparison.Ordinal))
        return "Etc/UTC";

    var tzdbSource = NodaTime.TimeZones.TzdbDateTimeZoneSource.Default;
    var tzi = TimeZoneInfo.FindSystemTimeZoneById(windowsZoneId);
    if (tzi == null) return null;
    var tzid = tzdbSource.MapTimeZoneId(tzi);
    if (tzid == null) return null;
    return tzdbSource.CanonicalIdMap[tzid];
}

When upgrading NodaTime to version 2.0, I now get a compile-time error saying MapTimeZoneId no longer exists. How do I get this function working again?

Jon Skeet
people
quotationmark

Currently, you need the same code that exists within the gut of Noda Time, but it's not very much:

internal static string WindowsToIana(string windowsZoneId)
{
    // Avoid UTC being mapped to Etc/GMT, which is the mapping in CLDR
    if (windowsZoneId == "UTC")
    {
        return "Etc/UTC";
    }
    var source = TzdbDateTimeZoneSource.Default;
    string result;
    // If there's no such mapping, result will be null.
    source.WindowsMapping.PrimaryMapping.TryGetValue(windowsZoneId, out result);
    // Canonicalize
    if (result != null)
    {
        result = source.CanonicalIdMap[result];
    }
    return result;
}

Notes:

  • This code will work with time zone IDs that aren't present on your system for whatever reason, but are present in CLDR
  • If this is all you're doing with Noda Time, consider using TimeZoneConverter instead
  • If you run on .NET Core on non-Windows systems, TimeZoneInfo.Local.Id will probably already be an IANA ID, so this code would return null in most cases.

I've filed an issue to handle the fact that this isn't mentioned in the migration guide.

people

See more on this question at Stackoverflow