Domanda

Questo problema si è verificato durante il cambio dell'ora legale. Dopo che è avvenuta la modifica, abbiamo notato che la nostra applicazione server ha iniziato a scrivere nel registro l'ora errata - un'ora avanti, il che significa che .NET memorizza nella cache il fuso orario. Abbiamo dovuto riavviare la nostra applicazione per risolvere questo problema. Ho scritto una semplice applicazione per riprodurre questo problema. Quando cambio il fuso orario mentre l'applicazione è in esecuzione, la proprietà DateTime.Now continua a produrre l'ora nel vecchio fuso orario. Qualcuno sa se esiste una soluzione alternativa per questo problema oltre al riavvio dell'applicazione?

È stato utile?

Soluzione

Sì, il fuso orario corrente viene memorizzato nella cache. Per una buona ragione, evita problemi con il codice non funzionante che utilizza DateTime.Now per implementare la misurazione del tempo trascorso. Tale codice tende a subire un attacco di cuore quando il tempo cambia improvvisamente di un'ora o più.

Dovrai chiamare System.Globalization.CultureInfo.ClearCachedData () per ripristinare il valore memorizzato nella cache. La prossima chiamata a DateTime.Now ora fornirà la nuova ora locale. Se usi la classe TimeZoneInfo .NET 3.5, dovrai anche chiamare il suo metodo ClearCachedData (). È possibile utilizzare l'evento SystemEvents.TimeChanged come trigger.

Altri suggerimenti

La raccomandazione più comune è quella di memorizzare DateTime.UtcNow e, quando si desidera mostrare all'utente l'ora locale, convertirla in contabilità dell'ora locale per l'ora legale.

.NET fornisce calcoli che prevedono l'ora legale con DaylightTime e TimeZone e le ToLocalTime può presumibilmente convertire UTC in contabilità locale per l'ora legale .

La classe pienamente qualificata sopra era leggermente disattivata, ma forse è cambiata in .NET 3.5.

System.Globalization.CultureInfo.CurrentCulture.ClearCachedData()

inoltre, non dimenticare di includere (in C # .NET) o importare (con VB.NET) il riferimento alla libreria System.Globalization.CultureInfo

Chiamalo subito prima di usare DateTime.Now . Sebbene sia probabilmente meglio chiamarlo nell'evento di avvio del tuo file Global.asax.

========== Assicurati inoltre di controllare il fuso orario su Windows Server stesso o sul tuo computer locale a seconda di dove è in esecuzione il server Web IIS.

Nel mio progetto avevo bisogno di ripristinare una serie di variabili se il Time (o Timezone) fosse cambiato. Per poter capire il fatto che questo evento si sia verificato, ho finito con un filtro WindowsMessage.

Sto usando .Net 2.0 quindi non ho potuto usare (o forse sto cercando nei posti sbagliati) ClearCachedData, quindi ho usato questo approccio con l'aiuto di un piccolo riflesso.

    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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top