Parse DateTime con la zona horaria de la forma PST / CEST / UTC / etc.

Estoy tratando de analizar una cadena internacional de fecha y hora similar a:

24-okt-08 21:09:06 CEST 

Hasta ahora tengo algo como:

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

El problema es, ¿qué debería usar para el ‘…’ en la cadena de formato? Al mirar la cadena de formato de fecha y hora personalizadas, MSDN no parece incluir una cadena de formato para analizar las zonas horarias en formato PST / CEST / GMT / UTC.

AFAIK no se reconocen las abreviaturas de zona horaria. Sin embargo, si reemplaza la abreviatura con el desplazamiento de la zona horaria, estará bien. P.ej:

 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); 

La respuesta rápida es que no puedes hacerlo.


Aquí está el porqué,

Hay una base de datos definitiva de las zonas horarias mundiales, puede obtenerla desde la IANA aquí .

El problema es que las abreviaturas de 3 o 4 letras tienen una asociación muchos a uno con las zonas horarias de IANA. Por ejemplo, "AMT" significa cosas diferentes, dependiendo de su cultura, en qué parte del mundo se encuentra y el contexto de su aplicación.

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

Si realmente quiere abordar esto, le sugiero usar Noda Time para representar su Instance . Tendrá que escribir un código para convertir las abreviaturas a una zona horaria IANA estándar.

No podemos hacer esto por usted, depende del contexto de su aplicación.


Otro buen ejemplo es "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 

Diccionario de abreviaturas si decide ir a la ruta de búsqueda y reemplazo (lo hice).

 Dictionary _timeZones = new Dictionary() { {"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"} }; 

Tengo dos respuestas porque no estoy exactamente seguro de lo que estás preguntando.

1) Veo que está utilizando CultureInfo, por lo que si solo desea formatear la fecha y la hora para que sean específicos de una cultura, separaría la fecha / hora y la zona horaria, aplicaría el método de cultivo en la fecha / hora y anexaría la zona horaria. Si “CEST” es diferente para culturas diferentes, tendrá que cambiarlo enumerando todas las opciones (tal vez en una statement de caso).

2) Si desea convertir la fecha / hora a otra zona horaria, no puede usar CultureInfo,

Sugiero leer: http://msdn.microsoft.com/en-us/library/ms973825.aspx

También puede usar .net Framework 3.5 clase TimeZoneInfo (diferente de TimeZone) para hacer su vida más fácil.

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

Nigromancia
Muchas respuestas malas aquí.

Así es como:

  1. Obtener la cadena (precondición: formato: ddd, dd MMM aaaa HH: mm: ss zzz)
  2. Obtener el último espacio en blanco
  3. Elimina zzz de la cadena, pero guarda el valor de zzz
  4. Offset de búsqueda para zzz
  5. Añadir desplazamiento a la cadena
 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); 

con

 private static System.Collections.Generic.Dictionary s_timeZoneOffsets = new System.Collections.Generic.Dictionary() { {"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"} }; 

Esto es lo que tenía que hacer.

Recibo la fecha y hora de javascript y luego la paso a ASP.NET para almacenarla en la base de datos de Oracle. Aquí está mi código de C # para los tiempos del este y el centro.

 string datetimevalue = hidfileDateTime.Value; datetimevalue= datetimevalue.Replace("EDT", "EST"); datetimevalue = datetimevalue.Replace("CDT", "CST"); if (datetimevalue.Contains("CST")) { filedt = DateTime.ParseExact(datetimevalue, "ddd MMM d HH:mm:ss CST yyyy", provider).ToUniversalTime().AddHours(1).ToLocalTime(); } else { filedt = DateTime.ParseExact(datetimevalue, "ddd MMM d HH:mm:ss EST yyyy", provider); }