.NET DateTime。现在更改时区时返回不正确的时间

.NET DateTime。现在更改时区时返回不正确的时间,.net,datetime,timezone,dst,.net,Datetime,Timezone,Dst,此问题发生在夏令时更改期间。在更改发生后,我们注意到服务器应用程序开始写入日志的时间不正确-提前一小时,这意味着.NET缓存时区偏移量。我们必须重新启动应用程序以解决此问题。 我编写了一个简单的应用程序来重现这个问题。当我在应用程序运行时更改时区时,DateTime.Now属性将继续在旧时区中生成时间。 有人知道除了重新启动应用程序外,是否还有解决此问题的方法吗?最常见的建议是存储DateTime.UtcNow,并且当您想向用户显示本地化时间时,将其转换为本地时间,以计算夏令时 .NET提供了与

此问题发生在夏令时更改期间。在更改发生后,我们注意到服务器应用程序开始写入日志的时间不正确-提前一小时,这意味着.NET缓存时区偏移量。我们必须重新启动应用程序以解决此问题。 我编写了一个简单的应用程序来重现这个问题。当我在应用程序运行时更改时区时,DateTime.Now属性将继续在旧时区中生成时间。
有人知道除了重新启动应用程序外,是否还有解决此问题的方法吗?

最常见的建议是存储DateTime.UtcNow,并且当您想向用户显示本地化时间时,将其转换为本地时间,以计算夏令时


.NET提供了与和类有关的夏令时计算,该方法可以将UTC转换为夏令时的本地记帐。

是的,当前时区被缓存。出于一个很好的原因,它避免了使用DateTime.Now实现运行时间测量的错误代码带来的麻烦。当时间突然改变一小时或更长时,这种代码往往会导致心脏病发作


您必须调用System.Globalization.CultureInfo.ClearCachedData()来重置缓存值。下一次调用DateTime.Now将给出新的本地时间。如果您使用.NET 3.5 TimeZoneInfo类,那么还需要调用其ClearCachedData()方法。您可以使用SystemEvents.TimeChanged事件作为触发器。

在我的项目中,如果时间(或时区)发生更改,我需要重置一系列变量。 为了得到发生此事件的事实,我最终使用了WindowsMessageFilter

我使用的是.NET2.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
私有mTZChangeFilter作为WindowsMessageFilter
mTZChangeFilter=新的WindowsMessageFilter()
AddHandler mTZChangeFilter.TimeChanged,AddressOf onTimeChanged
Application.RemoveMessageFilter(mTZChangeFilter)
公共类WindowsMessageFilter
实现IMessageFilter
_
作为布尔值的公共函数PreFilterMessage(ByRef m作为System.Windows.Forms.Message)实现System.Windows.Forms.IMessageFilter.PreFilterMessage
'Debug.Print(m.Msg.ToString)
如果m.Msg=30,则
重置时区()
RaiseEvent时间更改(Me)
如果结束
端函数
专用子时区()
Dim tz As Type=GetType(System.TimeZone)
Dim mth作为System.Reflection.MethodInfo
尝试
mth=tz.GetMethod(“ResetTimeZone”,BindingFlags.NonPublic或BindingFlags.Static)
调用(mth,无)
特例
Debug.Print(例如ToString)
结束尝试
端接头
末级

上面的完全限定类稍有偏离,但可能在.NET 3.5中有所改变

System.Globalization.CultureInfo.CurrentCulture.ClearCachedData()
另外,不要忘记(在C#.NET中)或(使用VB.NET)导入库参考
System.Globalization.CultureInfo

在使用
DateTime.Now
之前调用它。尽管最好在Global.asax文件的启动事件中调用它

==========
另外,请确保您正在检查Windows服务器本身或本地计算机上的时区,具体取决于IIS web服务器的运行位置。

您打败了我。。我将删除我的答案……)谢谢你的回答。我忘了提到我知道DateTime.UtcNow属性是一种解决方法。我希望有其他方法来解决这个问题。它看起来像.NET framework中的一个bug。也许,我应该编辑我的问题。感谢ClearCachedData()的提示。什么时候叫它最好?可能存在某个系统范围的广播事件?感谢您提供的信息。
SystemEvents.TimeChanged+=(发送方,args)=>System.Globalization.CultureInfo.CurrentCulture.ClearCachedData()将Windows的区域设置更改为不同的国家/地区(与前一个时区不同),不会影响TimeZone.CurrentTimeZone,即使在清除缓存数据后也是如此?检测到web应用程序假设