Pregunta

Este problema ocurrió durante el cambio de horario de verano. Después de que se produjo el cambio, hemos notado que nuestra aplicación de servidor comenzó a escribir en el registro la hora incorrecta, una hora por delante, lo que significa que el desplazamiento de la zona horaria de. 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 además de reiniciar la aplicación?

¿Fue útil?

Solución

Sí, la zona horaria actual se almacena en caché. Por una buena razón, evita problemas con el código roto que usa DateTime.Ahora para implementar la medición del tiempo transcurrido. Tal código tiende a sufrir un ataque al corazón cuando el tiempo cambia repentinamente por una hora o más.

Deberá llamar a System.Globalization.CultureInfo.ClearCachedData () para restablecer el valor almacenado en caché. La próxima llamada a DateTime.Now ahora dará la nueva hora local. Si utiliza la clase .NET 3.5 TimeZoneInfo, también deberá llamar a su método ClearCachedData (). Puede usar el evento SystemEvents.TimeChanged como desencadenante.

Otros consejos

La recomendación más común es almacenar DateTime.UtcNow y, cuando desee mostrarle la hora localizada al usuario, convertirla a la hora local para el horario de verano.

.NET proporciona cálculos que involucran el horario de verano con el DaylightTime y TimeZone , y las clases El método ToLocalTime supuestamente puede convertir UTC a contabilidad local para el horario de verano .

La clase completamente calificada anterior estaba ligeramente apagada, pero tal vez 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ámelo justo antes de usar DateTime.Now . Aunque probablemente sea mejor llamarlo en el evento de inicio de su archivo Global.asax.

========== También asegúrese de verificar la zona horaria en el propio servidor de Windows o en su máquina local, según dónde se esté ejecutando el servidor web IIS.

En mi proyecto, necesitaba restablecer una serie de variables si se cambiaba la hora (o zona horaria). Para poder entender el hecho de que este evento ocurrió, terminé usando un WindowsMessageFilter.

Estoy usando .Net 2.0, así que no pude usar (o tal vez estoy buscando en los lugares equivocados) ClearCachedData, así que usé este enfoque con la ayuda de una pequeña reflexión.

    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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top