Estamos desenvolvendo um aplicativo C # para um cliente de serviço da web. Isso será executado nos PCs com Windows XP.
Um dos campos retornados pelo serviço da web é um campo DateTime. O servidor retorna um campo no formato GMT, ou seja, com um "Z" no final.
No entanto, descobrimos que o .NET parece fazer algum tipo de conversão implícita e o tempo estava sempre em 12 horas.
O exemplo de código a seguir resolve isso em certa medida, pois a diferença de 12 horas se foi, mas não leva em consideração o horário de verão da Nova Zelândia.
CultureInfo ci = new CultureInfo("en-NZ");
string date = "Web service date".ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
De acordo com o site desta data :
Deslocamento UTC / GMT
Fuso horário padrão: UTC / GMT +12 horas
Horário de verão: +1 hora
Deslocamento atual do fuso horário: UTC / GMT +13 horas
Como nos ajustamos para a hora extra? Isso pode ser feito programaticamente ou é algum tipo de configuração nos PCs?
Z
horário refere-se ao UTC, não ao GMT. Os dois podem diferir em até 0,9 segundos.Respostas:
Para cadeias como
2012-09-19 01:27:30.000
,DateTime.Parse
não é possível saber de que fuso horário a data e a hora são.DateTime
possui uma propriedade Kind , que pode ter uma das três opções de fuso horário:OBSERVAÇÃO Se você deseja representar uma data / hora diferente do UTC ou do fuso horário local, use-o
DateTimeOffset
.Portanto, para o código em sua pergunta:
Você diz que sabe que tipo é, então diga.
Agora, assim que o sistema souber a hora UTC, basta ligar para
ToLocalTime
:Isso lhe dará o resultado desejado.
fonte
DateTime convertedTime = new DateTime(DateTime.Parse(dateStr).Ticks), DateTimeKind.Utc);
Kind
deDateTime
deUnspecified
paraUTC
é desnecessária.Unspecified
é assumido como tendoUTC
os seguintes propósitosToLocalTime
: msdn.microsoft.com/en-us/library/…Eu usaria a classe System.TimeZoneInfo se você estiver no .NET 3.5. Consulte http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx . Isso deve levar em consideração as alterações do horário de verão corretamente.
fonte
fonte
DateTime
objetos têm oKind
deUnspecified
, por padrão, o que, para efeitos deToLocalTime
se presume serUTC
.Para obter a hora local de um
Unspecified
DateTime
objeto, basta fazer o seguinte:A etapa de alterar o
Kind
deDateTime
deUnspecified
paraUTC
é desnecessária.Unspecified
é consideradoUTC
para os fins deToLocalTime
: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspxfonte
convertedDate.FromLocalTime();
irá converter paraUTC
.Sei que essa é uma pergunta mais antiga, mas me deparei com uma situação semelhante e queria compartilhar o que havia encontrado para futuros pesquisadores, possivelmente incluindo eu :).
DateTime.Parse()
pode ser complicado - veja aqui por exemplo.Se
DateTime
vier de um serviço da Web ou de alguma outra fonte com um formato conhecido, considere algo comoou, melhor ainda,
O
AssumeUniversal
sinalizador informa ao analisador que a data / hora já é UTC; a combinação deAssumeUniversal
eAdjustToUniversal
diz para não converter o resultado em horário "local", o que tentará fazer por padrão. (Pessoalmente, tento lidar exclusivamente com o UTC na (s) camada (s) de negócios / aplicativo / serviço. Mas ignorar a conversão para a hora local também acelera as coisas - em 50% ou mais nos meus testes, veja abaixo.)Aqui está o que estávamos fazendo antes:
Criámos o perfil do aplicativo e descobrimos que o DateTime.Parse representava uma porcentagem significativa do uso da CPU. (Aliás, o
CultureInfo
construtor não estava contribuiu significativamente para o uso da CPU.)Portanto, configurei um aplicativo de console para analisar uma sequência de data / hora 10000 vezes de várias maneiras. Conclusão:
Parse()
10 sParseExact()
(convertendo para local) 20-45 msParseExact()
(não convertendo para local) 10-15 ms... e sim, os resultados
Parse()
são em segundos , enquanto os outros estão em milissegundos .fonte
Gostaria apenas de adicionar uma nota geral de cautela.
Se tudo o que você está fazendo é obter a hora atual do relógio interno do computador para colocar uma data / hora no visor ou em um relatório, tudo está bem. Mas se você estiver salvando as informações de data / hora para referência posterior ou estiver computando datas / horas, cuidado!
Digamos que você determine que um navio de cruzeiro chegou a Honolulu em 20 de dezembro de 2007 às 15:00 UTC. E você quer saber a hora local.
1. Provavelmente há pelo menos três 'locais' envolvidos. Local pode significar Honolulu ou o local onde o computador está localizado ou o local onde o cliente está localizado.
2. Se você usar as funções internas para fazer a conversão, provavelmente estará errado. Isso ocorre porque o horário de verão está (provavelmente) atualmente em vigor no seu computador, mas NÃO estava em vigor em dezembro. Mas o Windows não sabe disso ... tudo o que tem é um sinalizador para determinar se o horário de verão está em vigor no momento. E, se estiver em vigor no momento, adicionará uma hora para uma data de dezembro.
3)O horário de verão é implementado de maneira diferente (ou não existe) em várias subdivisões políticas. Não pense que apenas porque seu país muda em uma data específica, outros países também o farão.
fonte
fonte
Não esqueça que se você já possui um objeto DateTime e não tem certeza se é UTC ou Local, é fácil usar os métodos diretamente no objeto:
A menos que o .net especificado use as configurações locais do PC. Eu teria uma leitura de: http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx
Pela aparência, o código pode ser algo como:
E, como mencionado acima, verifique novamente em qual configuração de fuso horário o servidor está. Existem artigos na rede sobre como afetar com segurança as alterações no IIS.
fonte
Em resposta à sugestão de Dana:
O exemplo de código agora se parece com:
A data original era 20/08/08; o tipo era UTC.
Tanto "convertedDate" como "dt" são os mesmos:
21/08/08 10:00:26; o tipo era local
fonte
Eu tive o problema de estar em um conjunto de dados sendo enviado através do fio (serviço da web para o cliente) que seria alterado automaticamente porque o campo DateType do DataColumn estava definido como local. Certifique-se de verificar qual é o DateType se você estiver pressionando DataSets.
Se você não deseja que ele mude, defina-o como Não especificado
fonte
Me deparei com essa pergunta porque estava tendo um problema com as datas UTC em que você retorna pela API do twitter (campo created_at em um status); Eu preciso convertê-los para DateTime. Nenhuma das respostas / amostras de código nas respostas desta página foi suficiente para me impedir de receber um erro "A string não foi reconhecida como um DateTime válido" (mas é o mais próximo que tenho de encontrar a resposta correta no SO)
A publicação deste link aqui, caso isso ajude alguém - a resposta que eu precisava foi encontrada nesta postagem do blog: http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ - basicamente use DateTime.ParseExact com uma string de formato em vez de DateTime.Parse
fonte