Ceux fournis par Microsoft pour une utilisation avec Windows et la TimeZoneInfoclasse .Net (lors de l'exécution sous Windows) sont identifiés par une valeur telle que "Eastern Standard Time".
Ceux fournis par l'IANA dans le TZDB et utilisés par la TimeZoneInfoclasse .NET lors de l'exécution sous Linux ou OSX sont identifiés par une valeur telle que "America/New_York".
De nombreuses API basées sur Internet utilisent les fuseaux horaires IANA, mais pour de nombreuses raisons, il peut être nécessaire de le convertir en un identifiant de fuseau horaire Windows, ou vice-versa.
La source principale des données pour la conversion entre les identificateurs de fuseau horaire Windows et IANA est le windowsZones.xmlfichier, distribué dans le cadre du projet Unicode CLDR . La dernière version de développement peut être trouvée ici .
Cependant , le CLDR n'est publié que deux fois par an. Ceci, associé à la cadence périodique des mises à jour Windows et aux mises à jour irrégulières de la base de données de fuseaux horaires IANA, complique l'utilisation directe des données CLDR. Gardez à l'esprit que les changements de fuseau horaire eux-mêmes sont effectués au gré des différents gouvernements du monde, et que tous les changements ne sont pas effectués avec un préavis suffisant pour en faire ces cycles de publication avant leurs dates d'entrée en vigueur respectives.
Il y a quelques autres cas extrêmes qui doivent être traités qui ne sont pas strictement couverts par le CLDR, et de nouveaux surgissent de temps en temps. Par conséquent, j'ai encapsulé la complexité de la solution dans la micro-bibliothèque TimeZoneConverter , qui peut être installée à partir de Nuget.
L'utilisation de cette bibliothèque est simple. Voici quelques exemples de conversion:
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"
Il est important de reconnaître que si un fuseau horaire IANA peut être mappé à un seul fuseau horaire Windows, l'inverse n'est pas vrai. Un seul fuseau horaire Windows peut être mappé à plusieurs fuseaux horaires IANA. Cela peut être vu dans les exemples ci-dessus, oùEastern Standard Time est mappé à la fois America/New_Yorket à America/Toronto. TimeZoneConverter fournira celui avec lequel CLDR marque "001", connu sous le nom de "zone dorée", à moins que vous ne fournissiez spécifiquement un code de pays et qu'il y ait une correspondance pour une zone différente dans ce pays.
Remarque: Cette réponse a évolué au fil des ans, de sorte que les commentaires ci-dessous peuvent s'appliquer ou non à la révision actuelle. Consultez l'historique des modifications pour plus de détails. Merci.
en utilisant cette méthode lors de la conversion (GMT+05:30) Chennai, Kolkata, Mumbai, New Delhidonne Asia/Calcuttaqu'il devrait être Asia/Kolkata. il semble que le TzdbDateTimeZoneSourcecontient d'anciennes valeurs.
Anto Subash
1
@MattJohnson lors de la conversion de la méthode Asia/Kolkatausing IanaToWindows, cela échoue. mais cela fonctionne avec Asia/Calcuttaquel est l'ancien nom. Vous avez mis à jour la méthode WindowsToIanamais vous rencontrez IanaToWindowségalement le même problème. quelques autres zones qui ne fonctionnent pas sont America/Argentina/Buenos_Aires, America/Indiana/Indianapolis, Asia/Kathmandu.
Anto Subash
1
@AntoJSubash - Encore une fois, bonne observation! J'ai édité la IanaToWindowsméthode pour compenser. Merci beaucoup!
Matt Johnson-Pint
2
@MattJohnson Je seconde l'observation de @ sirrocco. L'utilisation de l'identifiant canonique a également var canonical = tzdbSource.CanonicalIdMap[ ianaZoneId ]; links = Enumerable.Repeat( canonical, 1 ).Concat( links );fait l'affaire pour moi.
Johannes Rudolph
2
@sirrocco - Désolé, je n'ai pas vu votre commentaire plus tôt. Mise à jour des fonctions. Merci!
Matt Johnson-Pint
4
Je sais que c'est une vieille question, mais j'avais un cas d'utilisation que je pensais partager ici, car c'est le message le plus pertinent que j'ai trouvé lors de la recherche. Je développais une application .NET Core à l'aide d'un conteneur Linux Docker, mais pour un déploiement sur un serveur Windows. Je n'avais donc besoin que de mon conteneur Linux Docker pour prendre en charge les noms de fuseau horaire Windows. J'ai fait fonctionner cela sans changer le code de mon application en procédant comme suit:
cp /usr/share/zoneinfo/America/Chicago"/usr/share/zoneinfo/Central Standard Time"
cp /usr/share/zoneinfo/America/New_York"/usr/share/zoneinfo/Eastern Standard Time"
cp /usr/share/zoneinfo/America/Denver"/usr/share/zoneinfo/Mountain Standard Time"
cp /usr/share/zoneinfo/America/Los_Angeles"/usr/share/zoneinfo/Pacific Standard Time"
Ensuite, dans mon code .NET, ce qui suit a fonctionné sans aucune modification: TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
C'est une très bonne réflexion hors de la boîte! Cela semble correct, tant que vous couvrez quelques fuseaux horaires spécifiques. Gardez à l'esprit qu'il y en a plus que ces quatre aux États-Unis. Pour couvrir les 50 états actuels, vous devrez également ajouter des liens America/Phoenixvers "US Mountain Standard Time", Pacific/Honoluluvers "Hawaiian Standard Time", America/Anchoragevers "Alaskan Standard Time"et America/Adakvers "Aleutian Standard Time". Cela ne couvre pas les territoires américains ou les écarts historiques, mais vous aidera à démarrer.
Matt Johnson-Pint
2
Je ne recommanderais pas cette approche si l'intention est de couvrir le monde entier ou de traiter un identifiant de fuseau horaire valide. La liste est trop longue et trop volatile pour cela.
(GMT+05:30) Chennai, Kolkata, Mumbai, New Delhi
donneAsia/Calcutta
qu'il devrait êtreAsia/Kolkata
. il semble que leTzdbDateTimeZoneSource
contient d'anciennes valeurs.Asia/Kolkata
usingIanaToWindows
, cela échoue. mais cela fonctionne avecAsia/Calcutta
quel est l'ancien nom. Vous avez mis à jour la méthodeWindowsToIana
mais vous rencontrezIanaToWindows
également le même problème. quelques autres zones qui ne fonctionnent pas sontAmerica/Argentina/Buenos_Aires
,America/Indiana/Indianapolis
,Asia/Kathmandu
.IanaToWindows
méthode pour compenser. Merci beaucoup!var canonical = tzdbSource.CanonicalIdMap[ ianaZoneId ]; links = Enumerable.Repeat( canonical, 1 ).Concat( links );
fait l'affaire pour moi.Je sais que c'est une vieille question, mais j'avais un cas d'utilisation que je pensais partager ici, car c'est le message le plus pertinent que j'ai trouvé lors de la recherche. Je développais une application .NET Core à l'aide d'un conteneur Linux Docker, mais pour un déploiement sur un serveur Windows. Je n'avais donc besoin que de mon conteneur Linux Docker pour prendre en charge les noms de fuseau horaire Windows. J'ai fait fonctionner cela sans changer le code de mon application en procédant comme suit:
Ensuite, dans mon code .NET, ce qui suit a fonctionné sans aucune modification:
TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
la source
America/Phoenix
vers"US Mountain Standard Time"
,Pacific/Honolulu
vers"Hawaiian Standard Time"
,America/Anchorage
vers"Alaskan Standard Time"
etAmerica/Adak
vers"Aleutian Standard Time"
. Cela ne couvre pas les territoires américains ou les écarts historiques, mais vous aidera à démarrer.