What regions does TimeZoneInfo.TryConvertWindowsIdToIanaId support?

38 views Asked by At

I am trying to get all Iana time zones on a .net8 application. I can't use any open-source packages, so I am stuck with pulling DotNetIds out of the Windows registry. Right now, I am iterating through all TwoLetterIsoRegionNames over all DotNetIds to (try to) gather all IanaIds. I am not sure that it gets all IanaIds as the list is only 332 long, and according to the tzdb, the list is 352 cannonical zones and 597 total IanaIds. Is there a way to get all of these time zones this way or am I going to have to use TimeZoneConverter.

For example, I am only getting Indianapolis for Indiana, but there should be much more

                    var systemTimeZones = TimeZoneInfo.GetSystemTimeZones(); 
                    var isoRegions = CultureInfo.GetCultures(CultureTypes.AllCultures)
                        .Where(c => !c.IsNeutralCulture && c.LCID != 0x7f)
                        .Select(c => new RegionInfo(c.Name))
                        .GroupBy(r => r.TwoLetterISORegionName)
                        .Select(g => g.First())
                        .ToList();
                    
                    var timeZones = new List<TimeZone>();
                    foreach(var systemTimeZone in systemTimeZones)
                    {   
                        //Try to get all iana ids
                        var ianaIds = new HashSet<string>();
                        foreach(var isoRegion in isoRegions)
                        {
                            string ianaId;
                            if (!TimeZoneInfo.TryConvertWindowsIdToIanaId(systemTimeZone.Id, isoRegion.TwoLetterISORegionName, out ianaId))
                            {
                                continue;
                            }
                            ianaIds.Add(ianaId);
                        }

                        foreach (var ianaId in ianaIds)
                        {
                            if(!TimeZoneInfo.TryFindSystemTimeZoneById(ianaId, out ianaTimeZone))
                            {
                                continue;
                            }
                            Adds time zone to list.
                        }
                    }
1

There are 1 answers

1
Matt Johnson-Pint On BEST ANSWER

The TryConvertWindowsIdToIanaId method uses data from ICU that ultimately comes from the windowsZones.xml file in CLDR. The purpose of that data is to provide a Windows time zone that approximates one or more IANA time zones, thus allowing conversion between the two.

However, that file alone doesn't represent all IANA time zones. To do that, .NET would also have to take into account various aliases and administrative zones that are present in the timezone.xml file. It only does that for TryConvertIanaIdToWindowsId, so that alias are handled correctly in the reverse mapping.

So, while your question about which supported regions are available can be answered by looking at the territory field in windowsZones.xml, that won't help your goal of getting a list of all IANA time zones.

To get a list of all IANA time zones, on Linux or MacOS, you can just use TimeZoneInfo.GetSystemTimeZones. On Windows, there isn't a function built-in to .NET that can return this. However, you can use TZConvert.KnownIanaTimeZoneNames from my TimeZoneConverter library on any platform.