在夏令时更改期间出现此问题。更改发生后,我们注意到我们的服务器应用程序开始写入日志错误的时间 - 提前一小时,这意味着.NET缓存时区偏移。我们必须重新启动应用程序才能解决此问题。 我写了一个简单的应用程序来重现这个问题。当我在应用程序运行时更改时区时,DateTime.Now属性会在旧时区中生成时间。 除了重新启动应用程序之外,有没有人知道是否有解决此问题的方法?
答案 0 :(得分:46)
是的,缓存当前时区。有充分的理由,它避免了使用DateTime.Now来实现经过时间测量的破坏代码的麻烦。当时间突然改变一小时或更长时间时,这样的代码往往会遭受心脏病发作。
您必须调用System.Globalization.CultureInfo.ClearCachedData()来重置缓存的值。下一次调用DateTime.Now现在将给出新的本地时间。如果你完全使用.NET 3.5 TimeZoneInfo类,那么你还需要调用它的ClearCachedData()方法。您可以使用SystemEvents.TimeChanged事件作为触发器。
答案 1 :(得分:3)
最常见的建议是存储DateTime.UtcNow,并且当您想向用户显示本地化时间时,转换为本地时间会计以节省夏令时。
.NET提供了涉及DaylightTime和TimeZone类夏令时的计算,ToLocalTime方法可以将UTC转换为本地会计以获取夏令时。
答案 2 :(得分:1)
上面的完全限定类略有偏差,但可能在.NET 3.5中有所改变。
System.Globalization.CultureInfo.CurrentCulture.ClearCachedData()
也不要忘记包含(在C#.NET中)或导入(使用VB.NET)库引用System.Globalization.CultureInfo
在使用DateTime.Now
之前调用它。虽然最好在Global.asax文件的启动事件中调用它。
========== 还要确保在Windows Server本身或本地计算机上检查时区,具体取决于IIS Web服务器的运行位置。
答案 3 :(得分:0)
在我的项目中,如果更改了时间(或时区),我需要重置一系列变量。 所以我可以得到这个事件发生的事实我最终使用了一个WindowsMessageFilter。
我正在使用.Net 2.0,因此我无法使用(或者我可能在错误的地方寻找)ClearCachedData,所以我在一点反思的帮助下使用了这种方法。
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