为了概述我的项目,我有一个ASP.NET WebForm应用程序,允许用户登录和安排活动。事件处理由我为其编写Windows服务的本地Windows服务器处理和分派。
一切都运转良好,除了我有一些客户从东海岸登陆,一些从西海岸登陆。
有人可以建议我可以处理时区差异的工作流程吗?时区信息已经与每个客户端一起存储在数据库中。 我对如何应用时区信息感到困惑。
我知道DateTime
有一个ToUniversalTime()
方法,但它让我对它的工作方式感到困惑,因为它似乎需要知道DateTime
结构所属的时区能够将其转换为通用时间,据我所知,DateTime
结构没有在结构中内置时区信息。
有人可以向我解释一下吗?
答案 0 :(得分:1)
如果事件计划一次,则将其存储为DateTimeOffset
或UTC DateTime
是有意义的。如果您将其存储为DateTimeOffset
,您仍然可以将其显示给具有相关偏移量的用户 - 实际上,您可以将其显示给其他时区中的人,或者作为当地时间,或者作为原始用户的当地时间,其指示符与观看者的当地时间不同(如果您看到我的意思)。
如果它是经常性的(例如“每天凌晨4点”)那么这是不够的,因为它不会考虑DST的变化。相反,您应该存储本地时间和时区标识符。请参阅TimeZoneInfo.Id
和TimeZoneInfo.FindSystemTimeZoneById
。
作为一个明显的插件,您可能希望使用Noda Time API作为内置类型的更具表现力的替代方案......
您几乎肯定不正在使用DateTime.ToUniversalTime()
,因为它使用系统时区(即在您的服务器上),这几乎肯定是无关紧要的
答案 1 :(得分:0)
来自MSDN:
ToUniversalTime方法从本地时间转换DateTime值 到UTC。要将非本地时区的时间转换为UTC,请使用 TimeZoneInfo.ConvertTimeToUtc(DateTime,TimeZoneInfo)方法。至 转换已知其UTC偏移量的时间,使用ToUniversalTime 方法
从.NET Framework 2.0版开始,返回的值 ToUniversalTime方法由Kind的Kind属性决定 当前的DateTime对象。
未指定DateTime上的默认值Kind
,因此您的日期将被假定为当地时间。
答案 2 :(得分:0)
我们一直在研究类似的应用程序。我们将TimeZoneOffset和Scheduled Time存储在数据库表中。在客户端,TimeZOneOffset(以分钟为单位)考虑夏令时。计算方法如下:
Dim localZone As TimeZone = TimeZone.CurrentTimeZone
Dim StartTime As DateTime = UserEnteredStartDateTime 'from your web app
Dim TimeZoneOffset As Integer = localZone.GetUtcOffset(StartTime).TotalMinutes
服务器上的存储过程包括一个where子句,用于选择计划开始时间内的行加上30秒窗口,如下所示:
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()))