Pergunta

Fiquei me perguntando quais são exatamente os princípios de como as duas propriedades funcionam.Sei que o segundo é universal e basicamente não trata de fusos horários, mas alguém pode explicar detalhadamente como funcionam e qual deve ser usado em qual cenário?

Foi útil?

Solução

DateTime.UtcNow informa a data e a hora como seriam no Tempo Universal Coordenado, que também é chamado de fuso horário de Greenwich - basicamente como seria se você estivesse em Londres, Inglaterra, mas não durante o verão. DataHora.Agora fornece a data e a hora como apareceriam para alguém em sua localidade atual.

Eu recomendo usar DateTime.Now sempre que você exibe uma data para um ser humano - dessa forma, ele se sente confortável com o valor que vê - é algo que ele pode facilmente comparar com o que vê em seu relógio.Usar DateTime.UtcNow quando você deseja armazenar datas ou usá-las para cálculos posteriores dessa forma (em um modelo cliente-servidor), seus cálculos não ficam confusos com clientes em fusos horários diferentes do seu servidor ou entre si.

Outras dicas

É realmente muito simples, então acho que depende de qual é o seu público e de onde ele mora.

Se você não usa Utc, você deve conheça o fuso horário da pessoa para quem você está exibindo datas e horários - caso contrário, você dirá a ela que algo aconteceu às 15h no horário do sistema ou do servidor, quando realmente aconteceu às 17h no local onde ela mora.

Nós usamos DateTime.UtcNow porque temos um público global na web e porque prefiro não incomodar todos os usuários para que preencham um formulário indicando em que fuso horário eles vivem.

Também exibimos tempos relativos (2 horas atrás, 1 dia atrás, etc.) até que a postagem envelheça o suficiente para que o tempo seja "o mesmo", não importa onde você more na Terra.

Observe também a diferença de desempenho;DateTime.UtcNow é cerca de 30 vezes mais rápido que DateTime.Now, porque internamente DateTime.Now está fazendo muitos ajustes de fuso horário (você pode verificar isso facilmente com o Reflector).

Portanto, não use DateTime.Now para medições de tempo relativo.

Um conceito principal a ser entendido em .NET é que agora é agora em todo o mundo, não importa em que fuso horário você esteja.Então, se você carregar uma variável com DateTime.Now ou DateTime.UtcNow -- a atribuição é idêntica.* Seu DateTime object sabe em que fuso horário você está e leva isso em consideração, independentemente da atribuição.

A utilidade de DateTime.UtcNow é útil ao calcular datas além dos limites do horário de verão.Ou seja, em locais que participam do horário de verão, ora são 25 horas do meio-dia ao meio-dia do dia seguinte, ora são 23 horas entre meio-dia e meio-dia do dia seguinte.Se você deseja determinar corretamente o número de horas do horário A e do horário B, você precisa primeiro traduzir cada um para seus equivalentes UTC antes de calcular o TimeSpan.

Isto é coberto por um postagem no blog que escrevi isso explica melhor TimeSpan, e inclui um link para um artigo da MS ainda mais extenso sobre o assunto.

*Esclarecimento:Qualquer uma das atribuições armazenará a hora atual.Se você carregasse duas variáveis, uma via DateTime.Now() e o outro através DateTime.UtcNow() o TimeSpan a diferença entre os dois seria de milissegundos, não de horas, assumindo que você está em um fuso horário a horas de distância do GMT.Conforme observado abaixo, imprimir seus String os valores exibiriam strings diferentes.

Essa é uma boa pergunta.Estou revivendo-o para dar um pouco mais de detalhes sobre como o .Net se comporta com diferentes Kind valores.Como aponta @Jan Zich, na verdade é uma propriedade extremamente importante e é definida de forma diferente dependendo se você usa Now ou UtcNow.

Internamente a data é armazenada como Ticks que (ao contrário da resposta de @Carl Camera) é diferente dependendo se você usa Now ou UtcNow.

DateTime.UtcNow se comporta como outras línguas.Ele define Ticks para um valor baseado em GMT.Também define Kind para Utc.

DateTime.Now altera o Ticks valor para como seria se fosse a sua hora do dia no fuso horário GMT.Também define Kind para Local.

Se você estiver 6 horas atrasado (GMT-6), obterá o horário GMT de 6 horas atrás..Net realmente ignora Kind e trata esse momento como se tivesse sido há 6 horas, embora devesse ser “agora”.Isso quebra ainda mais se você criar um DateTime por exemplo, altere seu fuso horário e tente usá-lo.

Instâncias de DateTime com valores de 'Kind' diferentes NÃO são compatíveis.

Vejamos alguns códigos...

    DateTime utc = DateTime.UtcNow;
    DateTime now = DateTime.Now;
    Debug.Log (utc + " " + utc.Kind);  // 05/20/2015 17:19:27 Utc
    Debug.Log (now + " " + now.Kind);  // 05/20/2015 10:19:27 Local

    Debug.Log (utc.Ticks);  // 635677391678617830
    Debug.Log (now.Ticks);  // 635677139678617840

    now = now.AddHours(1);
    TimeSpan diff = utc - now;
    Debug.Log (diff);  // 05:59:59.9999990

    Debug.Log (utc <  now);  // false
    Debug.Log (utc == now);  // false
    Debug.Log (utc >  now);  // true

    Debug.Log (utc.ToUniversalTime() <  now.ToUniversalTime());  // true
    Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() >  now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() -  now.ToUniversalTime());  // -01:00:00.0000010

Como você pode ver aqui, as comparações e funções matemáticas não são convertidas automaticamente para tempos compatíveis.O Timespan deveria ter durado quase uma hora, mas em vez disso foram quase 6."utc <agora" deveria ser verdadeiro (até adicionei uma hora para ter certeza), mas ainda era falso.

Você também pode ver a 'solução alternativa' que é simplesmente converter para a hora universal em qualquer lugar que Kind Não é a mesma coisa.

Minha resposta direta à pergunta concorda com a recomendação da resposta aceita sobre quando usar cada uma delas.Você deveria sempre tentar trabalhar com DateTime objetos que possuem Kind=Utc, exceto durante E/S (exibição e análise).Isso significa que você quase sempre deve usar DateTime.UtcNow, exceto nos casos em que você está criando o objeto apenas para exibi-lo e descartando-o imediatamente.

DateTime não tem ideia de quais são os fusos horários.Sempre pressupõe que você está no horário local. UtcNow significa apenas "Subtrair meu fuso horário da hora".

Se você quiser usar datas com reconhecimento de fuso horário, use Deslocamento de data e hora, que representa uma data/hora com um fuso horário.Eu tive que aprender isso da maneira mais difícil.

Apenas um pequeno acréscimo aos pontos mencionados acima:a estrutura DateTime também contém um campo pouco conhecido chamado Tipo (pelo menos, eu não sabia disso há muito tempo).É basicamente apenas um sinalizador que indica se a hora é local ou UTC;ele não especifica o deslocamento real do UTC para horários locais.Além de indicar com que intenções o estudo foi construído, também influencia a forma como os métodos ParaUniversalTime() e ToLocalTime() trabalhar.

A resposta "simples" para a pergunta é:

DataHora.Agora retorna um Data hora valor que representa a hora atual do sistema (em qualquer fuso horário em que o sistema esteja sendo executado).O DataHora.Kind propriedade será DateTimeKind.Local

DateTime.UtcNow retorna um Data hora valor que representa o Tempo Universal Coordenado atual (também conhecido como UTC), que será o mesmo independentemente do fuso horário do sistema.O DataHora.Kind propriedade será DateTimeKind.Utc

DateTime.UtcNow é uma escala de tempo contínua e de valor único, enquanto DateTime.Now não é contínua ou de valor único.O principal motivo é o horário de verão, que não se aplica ao UTC.Portanto, o UTC nunca avança ou retrocede uma hora, enquanto a hora local (DateTime.Now) o faz.E quando salta para trás, o mesmo valor de tempo ocorre duas vezes.

DateTime.UtcNow é uma escala de tempo universal que omite o horário de verão.Portanto, o UTC nunca muda devido ao horário de verão.

Porém, DateTime.Now não é contínuo ou de valor único porque muda de acordo com o horário de verão.O que significa DateTime. Agora, o mesmo valor de tempo pode ocorrer duas vezes, deixando os clientes confusos.

Quando você precisar de um horário local para a máquina em que seu aplicativo é executado (como CEST para a Europa), use Agora.Se você quer um horário universal - UtcNow.É apenas uma questão de suas preferências - provavelmente criando um site local/aplicativo independente que você deseja usar no horário que o usuário tem - tão afetado pela configuração de fuso horário - DateTime.Now.

Lembre-se de que, para um site, é a configuração de fuso horário do servidor.Portanto, se você estiver exibindo a hora para o usuário, obtenha seu fuso horário preferido e mude a hora (apenas salve a hora Utc no banco de dados e modifique-a) ou especifique seu UTC.Se você esquecer de fazer isso, o usuário poderá ver algo como: postado 3 pontos negativos atrás e então um tempo no futuro próximo :)

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