[ACCEPTED]-.NET DateTime.Now returns incorrect time when time zone is changed-dst

Accepted answer
Score: 49

Yes, the current time zone is cached. For 13 a good reason, it avoids trouble with broken 12 code that uses DateTime.Now to implement 11 elapsed time measurement. Such code tends 10 to suffer a heart-attack when the time suddenly 9 changes by an hour or more.

You will have 8 to call System.Globalization.CultureInfo.ClearCachedData() to 7 reset the cached value. The next call to 6 DateTime.Now will now give the new local 5 time. If you use the .NET 3.5 TimeZoneInfo 4 class at all then you'll also need to call 3 its ClearCachedData() method. You can use 2 the SystemEvents.TimeChanged event as a 1 trigger.

Score: 3

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

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

Score: 1

The fully qualified class above was slightly 9 off, but perhaps it changed in .NET 3.5.

System.Globalization.CultureInfo.CurrentCulture.ClearCachedData()

also 8 don't forget to include (in C#.NET) or import 7 (with VB.NET) the library reference System.Globalization.CultureInfo

Call 6 it just before using DateTime.Now. Although it's probably 5 best to call it in the startup event of 4 your Global.asax file.

========== Also make 3 sure you're checking the timezone on Windows 2 Server itself, or your local machine depending 1 on where the IIS web server is running.

Score: 0

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

I'm 4 using .Net 2.0 so I couldn't use (or maybe 3 i'm looking in the wrong places for) the 2 ClearCachedData so I used this approach 1 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

More Related questions