Analise DateTime com o fuso horário do formulário PST / CEST / UTC / etc

Eu estou tentando analisar uma cadeia de data e hora internacional semelhante a:

24-okt-08 21:09:06 CEST 

Até agora eu tenho 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); 

O problema é o que devo usar para o ‘…’ na string de formatação? Observar a página personalizada do MSDN de String de formato de data e hora não parece listar uma string de formato para analisar fusos horários no formulário PST / CEST / GMT / UTC.

AFAIK as abreviaturas de fuso horário não são reconhecidas. No entanto, se você replace a abreviação pelo deslocamento do fuso horário, tudo ficará bem. Por exemplo:

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

A resposta rápida é que você não pode fazer isso.


Aqui está o porquê

Existe um database definitivo de fusos horários mundiais, você pode obtê-lo da IANA aqui .

O problema é que as abreviações de 3 ou 4 letras têm uma associação de muitos para um com os fusos horários da IANA. Por exemplo, "AMT" significa coisas diferentes, dependendo da sua cultura, em que parte do mundo você está e no contexto da sua aplicação.

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

Se você realmente quiser resolver isso, sugiro usar a Noda Time para representar sua Instance . Você terá que escrever algum código para converter as abreviações em um fuso horário padrão da IANA.

Não podemos fazer isso por você, depende do contexto do seu aplicativo.


Outro bom exemplo é "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 

Dicionário de abreviaturas, se você decidir ir a busca e replace a rota (eu fiz).

 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"} }; 

Eu tenho duas respostas porque não sei exatamente o que você está perguntando.

1) Eu vejo que você está usando CultureInfo, então se você quiser apenas formatar a data e a hora para ser específico da cultura, eu separaria a data / hora e fuso horário, aplicaria o método de cultura na data / hora e acrescentaria o fuso horário. Se “CEST” for diferente para diferentes culturas, você terá que alterá-lo listando todas as opções (talvez em uma declaração de caso).

2) Se você quiser que a data / hora seja convertida em outro fuso horário, não é possível usar CultureInfo,

Sugiro ler: http://msdn.microsoft.com/pt-br/library/ms973825.aspx

Você também pode usar o .net framework 3.5 class TimeZoneInfo (diferente do TimeZone) para tornar sua vida mais fácil.

http://msdn.microsoft.com/pt-br/library/system.timezoneinfo.aspx

Necromancing.
Muitas respostas ruins aqui.

É assim:

  1. Obter a cadeia (condição prévia: formato: ddd, dd MMy aaaa HH: mm: ss zzz)
  2. Obtenha o último espaço em branco
  3. Remova o zzz da string, mas salve o valor de zzz
  4. Deslocamento de pesquisa para zzz
  5. Adicionar deslocamento a string
 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); 

com

 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"} }; 

Aqui está o que eu tive que fazer.

Eu recebo o datetime do javascript e depois o transmito para o ASP.NET para armazenar no database Oracle. Aqui está o meu código c # para os tempos Oriental e Central.

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