Głównym źródłem danych do konwersji między identyfikatorami stref czasowych systemu Windows i IANA jest windowsZones.xml
plik rozpowszechniany w ramach projektu Unicode CLDR . Najnowszą wersję deweloperską można znaleźć tutaj .
Jednak CLDR jest wydawany tylko dwa razy w roku. To, wraz z okresową częstotliwością aktualizacji systemu Windows i nieregularnymi aktualizacjami bazy danych stref czasowych IANA, utrudnia po prostu bezpośrednie użycie danych CLDR. Należy pamiętać, że same zmiany stref czasowych są dokonywane z kaprysu różnych rządów na świecie i nie wszystkie zmiany są wprowadzane z odpowiednim wyprzedzeniem, aby mogły zostać wprowadzone do tych cykli wydawniczych przed ich datą wejścia w życie.
Istnieje kilka innych skrajnych przypadków, które należy rozpatrzyć, a które nie są objęte ścisłym rozporządzeniem CLDR, i od czasu do czasu pojawiają się nowe. Dlatego zawarłem złożoność rozwiązania w mikro-bibliotece TimeZoneConverter , którą można zainstalować z Nuget.
Korzystanie z tej biblioteki jest proste. Oto kilka przykładów konwersji:
string tz = TZConvert.IanaToWindows("America/New_York");
// Result: "Eastern Standard Time"
string tz = TZConvert.WindowsToIana("Eastern Standard Time");
// result: "America/New_York"
string tz = TZConvert.WindowsToIana("Eastern Standard Time", "CA");
// result: "America/Toronto"
Więcej przykładów znajduje się na stronie projektu .
Należy pamiętać, że podczas gdy strefę czasową IANA można odwzorować na jedną strefę czasową systemu Windows, sytuacja odwrotna nie jest prawdą. Pojedyncza strefa czasowa Windows może być mapowana na więcej niż jedną strefę czasową IANA. Można to zobaczyć w powyższych przykładach, gdzie Eastern Standard Time
jest odwzorowany zarówno na America/New_York
, jak i na America/Toronto
. TimeZoneConverter dostarczy ten oznaczony przez CLDR "001"
, zwany „złotą strefą”, chyba że podasz konkretnie kod kraju i pasuje do innej strefy w tym kraju.
Uwaga: ta odpowiedź ewoluowała przez lata, więc poniższe komentarze mogą, ale nie muszą, odnosić się do bieżącej wersji. Sprawdź historię zmian, aby uzyskać szczegółowe informacje. Dzięki.
(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi
dajeAsia/Calcutta
to, co powinnoAsia/Kolkata
. wygląda na to, żeTzdbDateTimeZoneSource
zawiera stare wartości.Asia/Kolkata
usingIanaToWindows
kończy się niepowodzeniem. ale działa zAsia/Calcutta
którą jest stara nazwa. zaktualizowałeś metodę,WindowsToIana
ale maszIanaToWindows
ten sam problem. Kilka innych stref, które nie pracują sąAmerica/Argentina/Buenos_Aires
,America/Indiana/Indianapolis
,Asia/Kathmandu
.IanaToWindows
metody kompensacji. Dziękuję bardzo!var canonical = tzdbSource.CanonicalIdMap[ ianaZoneId ]; links = Enumerable.Repeat( canonical, 1 ).Concat( links );
pomogło mi.Wiem, że to stare pytanie, ale miałem przypadek użycia, który chciałbym tutaj udostępnić, ponieważ jest to najbardziej odpowiedni post, który znalazłem podczas wyszukiwania. Opracowywałem aplikację .NET Core przy użyciu kontenera docker linux, ale do wdrożenia na serwerze Windows. Potrzebowałem więc tylko kontenera docker linux do obsługi nazw stref czasowych systemu Windows. Mam to działające bez zmiany kodu aplikacji, wykonując następujące czynności:
Następnie w moim kodzie .NET działały bez żadnych modyfikacji:
TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
źródło
America/Phoenix
do"US Mountain Standard Time"
,Pacific/Honolulu
do"Hawaiian Standard Time"
,America/Anchorage
do"Alaskan Standard Time"
iAmerica/Adak
do"Aleutian Standard Time"
. Nie obejmuje to terytoriów USA ani historycznych rozbieżności, ale na początek.