.NET DateTime.Now retorna a hora incorreta quando o fuso horário é alterado

Esse problema ocorreu durante a alteração do horário de verão. Depois que a alteração ocorreu, notamos que nosso aplicativo do servidor começou a gravar no tempo incorreto do log – uma hora à frente, o que significa que o .NET armazena em cache o deslocamento de fuso horário. Tivemos que reiniciar nosso aplicativo para resolver esse problema. Eu escrevi um aplicativo simples para reproduzir esse problema. Quando eu altero o fuso horário enquanto o aplicativo está em execução, a propriedade DateTime.Now continua produzindo a hora no fuso horário antigo. Alguém sabe se existe uma solução alternativa para esse problema além de reiniciar o aplicativo?

Sim, o fuso horário atual é armazenado em cache. Por um bom motivo, evita problemas com código quebrado que usa DateTime.Now para implementar a medição do tempo decorrido. Tal código tende a sofrer um ataque cardíaco quando o tempo muda repentinamente por uma hora ou mais.

Você terá que chamar System.Globalization.CultureInfo.ClearCachedData () para redefinir o valor em cache. A próxima chamada para DateTime.Now agora fornecerá a nova hora local. Se você usar a class .NET 3.5 TimeZoneInfo, você também precisará chamar seu método ClearCachedData (). Você pode usar o evento SystemEvents.TimeChanged como um triggersdor.

A recomendação mais comum é armazenar DateTime.UtcNow e, quando você deseja mostrar o tempo localizado para o usuário, converta para a hora local a contabilização do horário de verão.

O .NET fornece cálculos que envolvem horário de verão com as classs DaylightTime e TimeZone , e o método ToLocalTime supostamente pode converter o UTC em contabilidade local para o horário de verão.

A class totalmente qualificada acima foi ligeiramente desativada, mas talvez tenha sido alterada no .NET 3.5.

 System.Globalization.CultureInfo.CurrentCulture.ClearCachedData() 

também não se esqueça de include (em C # .NET) ou importar (com VB.NET) a referência da biblioteca System.Globalization.CultureInfo

Ligue antes de usar o DateTime.Now . Embora seja provavelmente melhor chamá-lo no evento de boot do seu arquivo Global.asax.

========== Verifique também se você está verificando o fuso horário no próprio Windows Server ou em sua máquina local, dependendo de onde o servidor Web IIS está sendo executado.

No meu projeto, eu precisava redefinir uma série de variables ​​se o horário (ou fuso horário) fosse alterado. Para que eu pudesse entender o fato desse evento, acabei usando um WindowsMessageFilter.

Eu estou usando o .net 2.0, então eu não poderia usar (ou talvez eu estou procurando nos lugares errados para) o ClearCachedData então eu usei essa abordagem com a ajuda de um pouco de reflection.

  Private mTZChangeFilter As WindowsMessageFilter mTZChangeFilter = New WindowsMessageFilter() AddHandler mTZChangeFilter.TimeChanged, AddressOf onTimeChanged Application.RemoveMessageFilter(mTZChangeFilter) Public Class WindowsMessageFilter Implements IMessageFilter  _ Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage ' Debug.Print(m.Msg.ToString) If m.Msg = 30 Then ResetTimeZone() RaiseEvent TimeChanged(Me) End If End Function Private Sub ResetTimeZone() Dim tz As Type = GetType(System.TimeZone) Dim mth As System.Reflection.MethodInfo Try mth = tz.GetMethod("ResetTimeZone", BindingFlags.NonPublic Or BindingFlags.Static) mth.Invoke(mth, Nothing) Catch ex As Exception Debug.Print(ex.ToString) End Try End Sub end class