Pergunta

Como é que a conversão para UTC do trabalho formato DateTime padrão?

Mais especificamente, se eu criar um objeto DateTime em um fuso horário e, em seguida, mudar para outro fuso horário e ToUniversalTime() rodar nele, como ele sabe a conversão foi feito corretamente e que o tempo ainda é representado com precisão?

Foi útil?

Solução

Não há fuso horário implícito anexado a um objeto DateTime. Se você executar ToUniversalTime() nele, ele usa o fuso horário do contexto que o código está sendo executado.

Por exemplo, se eu criar um DateTime da época de 1/1/1970, dá-me o mesmo objeto DateTime não importa onde no mundo que eu sou.

Se eu executar ToUniversalTime() nele quando estou executando o código em Greenwich, então eu obter o mesmo tempo. Se eu fizer isso, enquanto eu viver em Vancouver, então eu recebo um objeto DateTime compensação de -8 horas.

Este é por isso que é importante para obter informações relacionadas loja tempo em seu banco de dados como vezes UTC quando você precisa fazer qualquer tipo de conversão de data ou localização. Considere se a sua base de código got foi transferida para uma instalação de servidor em outro fuso horário;)

Edit: nota de resposta de Joel - objetos DateTime por padrão são digitados como DateTimeKind.Local. Se você analisar uma data e defini-lo como DateTimeKind.Utc, executa então ToUniversalTime() nenhuma conversão.

E aqui está um artigo sobre "Melhores práticas de codificação com data Times" , e um artigo sobre Convertendo DateTimes com .Net .

Outras dicas

Em primeiro lugar, ele verifica se o Kind do DateTime é conhecido por ser UTC já. Se assim for, ele retorna o mesmo valor.

Caso contrário, é assumido como sendo um horário local - que é local para o computador que está sendo executado, e em particular na zona de tempo que o computador estava usando quando alguma propriedade privada foi primeiro preguiçosamente inicializado. Isso significa que se você alterar o fuso horário após seu aplicativo foi iniciado, há uma boa chance de ele ainda estar usando o antigo.

O fuso horário contém informações suficientes para converter uma hora local para um tempo UTC, ou vice-versa, embora há momentos em que isso é ambígua ou inválido. (Há momentos em locais que ocorrem duas vezes, e horas locais, o que nunca ocorrem devido ao horário de verão.) As regras para lidar com esses casos são especificados no a documentação :

Se o valor de instância de data e hora é um tempo ambígua, este método pressupõe que é um tempo padrão. (A tempo ambígua é aquele que pode mapear quer para um tempo padrão ou a um horário de verão no horário local zona) Se o exemplo data e hora valor é uma hora inválida, este método simplesmente subtrai a hora local de UTC do fuso horário local de deslocamento para voltar UTC. (Uma hora inválida é um que não existe por causa da aplicação da hora de Verão regras de ajuste.)

O valor retornado terá um Kind de DateTimeKind.Utc, por isso, se você chama ToUniveralTime em que não aplicará o deslocamento novamente. (Esta é uma grande melhoria sobre .NET 1.1!)

Se você quiser um fuso horário não-local, você deve usar TimeZoneInfo que foi introduzido no .NET 3.5 (existem soluções hacky para versões anteriores, mas não é legal). Para representar um instante no tempo, você deve considerar o uso DateTimeOffset que foi introduzido em .NET 2.0SP1, .NET3.0SP1 e .NET 3.5. No entanto, que ainda não tem um fuso horário real associado com ele - apenas um deslocamento do UTC. Isso significa que você não sabe o que hora local será uma hora mais tarde, por exemplo - as regras do horário de verão pode variar entre fusos horários que aconteceu para usar o mesmo deslocamento para aquele instante particular. TimeZoneInfo é projetado para ter regras históricas e futuras em conta, em oposição a TimeZone que é um pouco simplista.

Basicamente o apoio em .NET 3.5 é muito melhor do que era, mas ainda deixa algo a desejar para a aritmética calendário próprio. Qualquer um gosta de portar Joda Tempo para .NET? ;)

O @womp disse , com a adição que ele verifica propriedade Kind do DateTime para ver se ele pode ser uma data UTC.

DateTime.ToUniversalTime remove o deslocamento do fuso horário local para normalizar um DateTime em UTC fuso horário. Se você usar DateTime.ToLocalTime no valor normalizado em outro fuso horário, o deslocamento de fuso horário desse fuso horário será adicionado ao valor normalizado para a representação correto em que fuso horário.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top