views:

1454

answers:

3

This problem occurred during daylight saving time change. After the change occurred, we've noticed that our server application started writing into the log incorrect time - one hour ahead which means that .NET caches time zone offset. We had to restart our application to resolve this problem. I wrote a simple application to reproduce this problem. When I change the time zone while application is running, DateTime.Now property keeps producing the time in the old time zone. Does anybody know if there is a workaround for this problem apart from restarting the application?

+2  A: 

The most common recommendation is to store DateTime.UtcNow and, when you want to show localized time to the user, convert to local time accounting for daylight savings.

.NET provides for calculations involving daylight savings time with the DaylightTime and TimeZone classes, and the ToLocalTime method supposedly can convert UTC to local accounting for daylight savings time.

Will
You beat me.. I'll delete my answer.. ;)
Stefan
Thank you for the answer. I forgot to mention that I knew about DateTime.UtcNow property as a workaround. I was hoping there was other way to tackle this problem. It looks like a bug in .NET framework. Perhaps, I should edit my question.
Greg
+6  A: 

Yes, the current time zone is cached. You would have to call System.Globalization.CultureInfo.ClearCachedData() to reset it. If you use the .NET 3.5 TimeZoneInfo class at all, it has its own ClearCachedData() method.

Hans Passant
A: 

In my project I needed to Reset a series of variables if the Time (or Timezone) was changed. So that I could get the fact this event occurred I ended up using a WindowsMessageFilter.

I'm using .Net 2.0 so I couldn't use (or maybe i'm looking in the wrong places for) the ClearCachedData so I used this approach with the help of a little reflection.

    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
Paul Farry