.net - horaria - timezoneinfo c#
.NET DateTime.Now devuelve una hora incorrecta cuando se cambia la zona horaria (4)
Este problema ocurrió durante el cambio de horario de verano. Después de que ocurriera el cambio, notamos que nuestra aplicación de servidor comenzó a escribir en el registro de tiempo incorrecto, una hora más adelante, lo que significa que .NET almacena en caché la compensación de zona horaria. Tuvimos que reiniciar nuestra aplicación para resolver este problema. Escribí una aplicación simple para reproducir este problema. Cuando cambio la zona horaria mientras se ejecuta la aplicación, la propiedad DateTime.Now sigue produciendo la hora en la zona horaria anterior. ¿Alguien sabe si hay una solución para este problema aparte de reiniciar la aplicación?
En mi proyecto, necesitaba restablecer una serie de variables si se cambiaba la hora (o la zona horaria). Para poder ver el hecho de que ocurrió este evento, terminé usando un WindowsMessageFilter.
Estoy usando .Net 2.0, así que no pude usar (o tal vez estoy buscando en los lugares incorrectos) ClearCachedData, así que utilicé este enfoque con la ayuda de un pequeño reflejo.
Private mTZChangeFilter As WindowsMessageFilter
mTZChangeFilter = New WindowsMessageFilter()
AddHandler mTZChangeFilter.TimeChanged, AddressOf onTimeChanged
Application.RemoveMessageFilter(mTZChangeFilter)
Public Class WindowsMessageFilter
Implements IMessageFilter
<System.Diagnostics.DebuggerStepThrough()> _
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
La clase completamente calificada anterior estaba ligeramente desactivada, pero quizás cambió en .NET 3.5.
System.Globalization.CultureInfo.CurrentCulture.ClearCachedData()
tampoco olvide incluir (en C # .NET) o importar (con VB.NET) la referencia de biblioteca System.Globalization.CultureInfo
Llámalo justo antes de usar DateTime.Now
. Aunque probablemente sea mejor llamarlo en el evento de inicio de su archivo Global.asax.
========== Además, asegúrese de estar comprobando la zona horaria en el servidor Windows mismo o en su máquina local, dependiendo de dónde se esté ejecutando el servidor web IIS.
La recomendación más común es almacenar DateTime.UtcNow y, cuando desee mostrar la hora localizada al usuario, convierta a la contabilidad de tiempo local para el horario de verano.
.NET proporciona cálculos que implican el horario de verano con las clases DaylightTime y TimeZone , y el método ToLocalTime supuestamente puede convertir el UTC a la contabilidad local para el horario de verano.
Sí, la zona horaria actual está en la memoria caché. Por una buena razón, evita problemas con el código dañado que usa DateTime.Now para implementar la medición del tiempo transcurrido. Tal código tiende a sufrir un ataque al corazón cuando el tiempo cambia de repente por una hora o más.
Tendrá que llamar a System.Globalization.CultureInfo.ClearCachedData () para restablecer el valor en caché. La próxima llamada a DateTime.Now ahora dará la nueva hora local. Si utiliza la clase .NET 3.5 TimeZoneInfo en absoluto, también deberá llamar a su método ClearCachedData (). Puede utilizar el evento SystemEvents.TimeChanged como desencadenante.