web-dev-qa-db-fra.com

Analyser DateTime avec le fuseau horaire de la forme PST/CEST/UTC/etc

J'essaie d'analyser une chaîne datetime internationale similaire à:

24-okt-08 21:09:06 CEST

Jusqu'à présent, j'ai quelque chose comme:

CultureInfo culture = CultureInfo.CreateSpecificCulture("nl-BE");
DateTime dt = DateTime.ParseExact("24-okt-08 21:09:06 CEST",
    "dd-MMM-yy HH:mm:ss ...", culture);

Le problème est que dois-je utiliser pour le "..." dans la chaîne de format? L'examen de la chaîne de format de date et d'heure Custom La page MSDN ne semble pas répertorier une chaîne de format permettant d'analyser les fuseaux horaires sous la forme PST/CEST/GMT/UTC.

43
thelsdj

Autant que je sache, les abréviations de fuseau horaire ne sont pas reconnues. Toutefois, si vous remplacez l'abréviation par le décalage de fuseau horaire, ce sera OK. Par exemple.:

DateTime dt1 = DateTime.ParseExact("24-okt-08 21:09:06 CEST".Replace("CEST", "+2"), "dd-MMM-yy HH:mm:ss z", culture);
DateTime dt2 = DateTime.ParseExact("24-okt-08 21:09:06 CEST".Replace("CEST", "+02"), "dd-MMM-yy HH:mm:ss zz", culture);
DateTime dt3 = DateTime.ParseExact("24-okt-08 21:09:06 CEST".Replace("CEST", "+02:00"), "dd-MMM-yy HH:mm:ss zzz", culture);
32
Panos

La réponse rapide est que vous ne pouvez pas le faire.


Voici pourquoi

Il existe une base de données définitive sur les fuseaux horaires dans le monde. Vous pouvez l'obtenir auprès de IANA ici .

Le problème est que les abréviations de 3 ou 4 lettres ont une association multiple avec les fuseaux horaires IANA. Par exemple "AMT" signifie différentes choses, selon votre culture, la région du monde où vous vous trouvez et le contexte de votre application.

AMT "Armenia Time" Asia          UTC + 4 hours 
AMT "Amazon Time"  South America UTC - 4 hours 

Si vous voulez vraiment vous attaquer à cela, je suggère d’utiliser Noda Time pour représenter votre Instances. Vous devrez écrire du code pour convertir les abréviations en un fuseau horaire IANA standard.

Nous ne pouvons pas le faire pour vous, cela dépend du contexte de votre application.


Un autre bon exemple est "CST" .

CST "China Standard Time"   Asia            UTC + 8 hours 
CST "Central Standard Time" Central America UTC - 6 hours 
CST "Cuba Standard Time"    Caribbean       UTC - 5 hours 
CST "Central Standard Time" North America   UTC - 6 hours 
22
Jodrell

Dictionnaire des abréviations si vous décidez d'aller chercher et remplacer la route (j'ai fait).

Dictionary<string, string> _timeZones = new Dictionary<string, string>() {
            {"ACDT", "+1030"},
            {"ACST", "+0930"},
            {"ADT", "-0300"},
            {"AEDT", "+1100"},
            {"AEST", "+1000"},
            {"AHDT", "-0900"},
            {"AHST", "-1000"},
            {"AST", "-0400"},
            {"AT", "-0200"},
            {"AWDT", "+0900"},
            {"AWST", "+0800"},
            {"BAT", "+0300"},
            {"BDST", "+0200"},
            {"BET", "-1100"},
            {"BST", "-0300"},
            {"BT", "+0300"},
            {"BZT2", "-0300"},
            {"CADT", "+1030"},
            {"CAST", "+0930"},
            {"CAT", "-1000"},
            {"CCT", "+0800"},
            {"CDT", "-0500"},
            {"CED", "+0200"},
            {"CET", "+0100"},
            {"CEST", "+0200"},
            {"CST", "-0600"},
            {"EAST", "+1000"},
            {"EDT", "-0400"},
            {"EED", "+0300"},
            {"EET", "+0200"},
            {"EEST", "+0300"},
            {"EST", "-0500"},
            {"FST", "+0200"},
            {"FWT", "+0100"},
            {"GMT", "GMT"},
            {"GST", "+1000"},
            {"HDT", "-0900"},
            {"HST", "-1000"},
            {"IDLE", "+1200"},
            {"IDLW", "-1200"},
            {"IST", "+0530"},
            {"IT", "+0330"},
            {"JST", "+0900"},
            {"JT", "+0700"},
            {"MDT", "-0600"},
            {"MED", "+0200"},
            {"MET", "+0100"},
            {"MEST", "+0200"},
            {"MEWT", "+0100"},
            {"MST", "-0700"},
            {"MT", "+0800"},
            {"NDT", "-0230"},
            {"NFT", "-0330"},
            {"NT", "-1100"},
            {"NST", "+0630"},
            {"NZ", "+1100"},
            {"NZST", "+1200"},
            {"NZDT", "+1300"},
            {"NZT", "+1200"},
            {"PDT", "-0700"},
            {"PST", "-0800"},
            {"ROK", "+0900"},
            {"SAD", "+1000"},
            {"SAST", "+0900"},
            {"SAT", "+0900"},
            {"SDT", "+1000"},
            {"SST", "+0200"},
            {"SWT", "+0100"},
            {"USZ3", "+0400"},
            {"USZ4", "+0500"},
            {"USZ5", "+0600"},
            {"USZ6", "+0700"},
            {"UT", "-0000"},
            {"UTC", "-0000"},
            {"UZ10", "+1100"},
            {"WAT", "-0100"},
            {"WET", "-0000"},
            {"WST", "+0800"},
            {"YDT", "-0800"},
            {"YST", "-0900"},
            {"ZP4", "+0400"},
            {"ZP5", "+0500"},
            {"ZP6", "+0600"}
        };
9
Jussi Palo

J'ai deux réponses parce que je ne suis pas tout à fait sûr de ce que vous demandez.

1) Je vois que vous utilisez CultureInfo, donc si vous voulez juste formater La date et l’heure étant spécifiques à la culture, je séparerais la date/heure et le fuseau horaire, appliquerais la méthode de culture à la date/heure et ajoutez le fuseau horaire. Si "CEST" est différent pour différentes cultures, vous devrez le modifier en listant toutes les options (peut-être dans une déclaration de cas). 

2) Si vous souhaitez que la date/heure soit convertie en un autre fuseau horaire, vous ne pouvez pas utiliser CultureInfo. 

Je suggère de lire: http://msdn.Microsoft.com/en-us/library/ms973825.aspx

Vous pouvez également utiliser la classe TimeZoneInfo (différente de TimeZone) du framework 3.5 .net pour vous simplifier la vie.

http://msdn.Microsoft.com/en-us/library/system.timezoneinfo.aspx

3
hmak

C'est ainsi:

  1. Obtenir la chaîne (condition préalable: format: jj, jj MMM aaaa HH: mm: ss zzz)
  2. Obtenez le dernier espace
  3. Supprimez zzz de la chaîne, mais enregistrez la valeur de zzz
  4. Recherche offset pour zzz
  5. Ajouter un décalage à la chaîne
string dateString = reader.ReadContentAsString();
int timeZonePos = dateString.LastIndexOf(' ') + 1;
string tz = dateString.Substring(timeZonePos);
dateString = dateString.Substring(0, dateString.Length - tz.Length );
dateString += s_timeZoneOffsets[tz];

// https://msdn.Microsoft.com/en-us/library/w2sa9yss(v=vs.110).aspx
//string es = reader.ReadElementString("pubDate");
this.m_value = System.DateTime.ParseExact(dateString, "ddd, dd MMM yyyy HH:mm zzz", System.Globalization.CultureInfo.InvariantCulture);

avec 

private static System.Collections.Generic.Dictionary<string, string> s_timeZoneOffsets =
    new System.Collections.Generic.Dictionary<string, string>() {
    {"ACDT", "+10:30"},
    {"ACST", "+09:30"},
    {"ADT", "-03:00"},
    {"AEDT", "+11:00"},
    {"AEST", "+10:00"},
    {"AHDT", "-09:00"},
    {"AHST", "-10:00"},
    {"AST", "-04:00"},
    {"AT", "-02:00"},
    {"AWDT", "+09:00"},
    {"AWST", "+08:00"},
    {"BAT", "+03:00"},
    {"BDST", "+02:00"},
    {"BET", "-11:00"},
    {"BST", "-03:00"},
    {"BT", "+03:00"},
    {"BZT2", "-03:00"},
    {"CADT", "+10:30"},
    {"CAST", "+09:30"},
    {"CAT", "-10:00"},
    {"CCT", "+08:00"},
    {"CDT", "-05:00"},
    {"CED", "+02:00"},
    {"CET", "+01:00"},
    {"CEST", "+02:00"},
    {"CST", "-06:00"},
    {"EAST", "+10:00"},
    {"EDT", "-04:00"},
    {"EED", "+03:00"},
    {"EET", "+02:00"},
    {"EEST", "+03:00"},
    {"EST", "-05:00"},
    {"FST", "+02:00"},
    {"FWT", "+01:00"},
    {"GMT", "+00:00"},
    {"GST", "+10:00"},
    {"HDT", "-09:00"},
    {"HST", "-10:00"},
    {"IDLE", "+12:00"},
    {"IDLW", "-12:00"},
    {"IST", "+05:30"},
    {"IT", "+03:30"},
    {"JST", "+09:00"},
    {"JT", "+07:00"},
    {"MDT", "-06:00"},
    {"MED", "+02:00"},
    {"MET", "+01:00"},
    {"MEST", "+02:00"},
    {"MEWT", "+01:00"},
    {"MST", "-07:00"},
    {"MT", "+08:00"},
    {"NDT", "-02:30"},
    {"NFT", "-03:30"},
    {"NT", "-11:00"},
    {"NST", "+06:30"},
    {"NZ", "+11:00"},
    {"NZST", "+12:00"},
    {"NZDT", "+13:00"},
    {"NZT", "+12:00"},
    {"PDT", "-07:00"},
    {"PST", "-08:00"},
    {"ROK", "+09:00"},
    {"SAD", "+10:00"},
    {"SAST", "+09:00"},
    {"SAT", "+09:00"},
    {"SDT", "+10:00"},
    {"SST", "+02:00"},
    {"SWT", "+01:00"},
    {"USZ3", "+04:00"},
    {"USZ4", "+05:00"},
    {"USZ5", "+06:00"},
    {"USZ6", "+07:00"},
    {"UT", "-00:00"},
    {"UTC", "-00:00"},
    {"UZ10", "+11:00"},
    {"WAT", "-01:00"},
    {"WET", "-00:00"},
    {"WST", "+08:00"},
    {"YDT", "-08:00"},
    {"YST", "-09:00"},
    {"ZP4", "+04:00"},
    {"ZP5", "+05:00"},
    {"ZP6", "+06:00"}
};
0
Stefan Steiger