只是为了概述我的项目,我有一个ASP.NET WebForm应用程序,允许用户登录并安排事件。事件处理是由本地Windows Server处理和派遣的,我为此写了Windows服务。
一切正常,除了我有一些客户从东海岸登录,有些是从西海岸登录的。
有人可以建议我如何处理时区差异的可能工作流程吗?时区信息已经与每个客户端一起存储在数据库中。 我只是对如何应用时区信息感到困惑。
我知道DateTime
有一个ToUniversalTime()
方法,但它使我对它的工作方式感到困惑,因为几乎需要知道DateTime
结构的时区域的时间区域才能将其转换为通用时间,并且我知道,DateTime
结构没有直接构建的时区信息。
有人可以向我解释一下吗?
如果事件计划发生曾经,则将其存储为DateTimeOffset
或UTC DateTime
是有意义的。如果将其存储为DateTimeOffset
,则仍然可以通过相关偏移向用户显示它 - 实际上,您可以在其他时区或原始时区显示给人们用户的本地时间,指示它与观看者的本地时间不同(如果您明白了我的意思)。
如果它是复发的(例如"每天凌晨4点"),那么这是不够的,因为它不会考虑DST的变化。相反,您应该存储 local 时间和时区标识符。参见TimeZoneInfo.Id
和TimeZoneInfo.FindSystemTimeZoneById
。
作为公然的插头,您可能希望将Noda Time API用作内置类型的更具表现力的替代品...
您几乎应该肯定地使用DateTime.ToUniversalTime()
,因为它使用 system 时区(即在您的服务器上),几乎可以肯定应该是无关紧要的。
来自msdn:
TouniverSaltime方法从当地时间转换DateTime值 到UTC。要将非本地时区中的时间转换为UTC,请使用 TimeZoneInfo.convertTimEtoutc(DateTime,TimeZoneInfo)方法。到 转换一个已知UTC的偏移的时间,请使用TouriverSaltime 方法。
从.NET Framework 2.0开始,该值由 touriversaltime方法由 当前的日期对象。
未指定DateTime上Kind
的默认值,因此您的日期被认为是本地时间。
我们一直在处理类似的应用程序。我们将TimeZoneOffset和计划时间存储在数据库表中。在客户端,TimeZoneOffset(以几分钟为单位)考虑了日光节省的时间。计算如下:
Dim localZone As TimeZone = TimeZone.CurrentTimeZone
Dim StartTime As DateTime = UserEnteredStartDateTime 'from your web app
Dim TimeZoneOffset As Integer = localZone.GetUtcOffset(StartTime).TotalMinutes
服务器上的存储过程包含一个选择在计划开始时间内的行以及30秒窗口的Where子句:
:SELECT Invitations.ID, Invitations.OrganizerName, Invitations.OrganizerEmail, Invitations.EMailBody, Invitations.[Subject]
FROM Invitations
WHERE (Invitations.MailSent=0)
And (Invitations.SendTime Between DateAdd(mi,Invitations.TimeZOneOffset,GETUTCDATE())
And DateAdd(s,(Invitations.TimeZoneOffset*60)+30,GETUTCDATE()))