Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

noda time iana mapping of Etc/UTC to Windows timezone

Tags:

c#

nodatime

I have a global website that is passing the IANA timezone id to the server and using Noda Time to map to the Windows Timezone in c# 5 web app.

"Etc/UTC" is being passed to the server but Noda Time can not map it to a Windows time zone. How can I map an IANA timezone id?

public TimeZoneInfo GetTimeZoneByIanaId(string ianaTimeZoneId)
{
    TzdbDateTimeZoneSource timeZoneSource = TzdbDateTimeZoneSource.Default;
    IList<MapZone> zoneMaps = timeZoneSource.WindowsMapping.MapZones;

    // resolve any link, since the CLDR doesn't necessarily use canonical IDs
    IList<string> mapZoneIds = timeZoneSource.CanonicalIdMap.Where(map => map.Value.Equals(ianaTimeZoneId, StringComparison.OrdinalIgnoreCase)).Select(x => x.Key).ToList();
    MapZone mapZone = zoneMaps.FirstOrDefault(zoneMap => zoneMap.TzdbIds.Any(mapZoneIds.Contains));

    if (mapZone == null)
    {
        throw new TimeZoneNotFoundException("Unable to determine the clients timezone using the jsTimezoneDetect plugin");
    }

    TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(mapZone.WindowsId);

    if (timeZone == null)
    {
        throw new TimeZoneNotFoundException("Unable to determine the clients timezone from NodaTime");
    }

    return timeZone;
}
like image 841
user3772576 Avatar asked Jun 24 '14 19:06

user3772576


1 Answers

As Jon pointed out, the CLDR mapping is not there for "Etc/UTC". Instead, the CLDR maps the Windows "UTC" time zone to "Etc/GMT". IMHO - this is in error.

The CLDR requires "stable identifiers", so it has not traditionally updated its mappings when time zone names change. Instead, one would normally follow the "links" in the time zone database to map to the canonical zone.

However - the TZDB doesn't consider "Etc/GMT" to be a link for "Etc/UTC". They are two distinct zones. There's also "Etc/UCT". This is so that applications that rely on the TZDB for time zone abbreviations can use their choice of abbreviation (GMT, UTC, or UCT). (See discussion here.)

Anyway - thanks for reminding us of this problem. I updated the mapping functions to take this into account.

like image 154
Matt Johnson-Pint Avatar answered Oct 20 '22 09:10

Matt Johnson-Pint