3

为了概述我的项目,我有一个 ASP.NET WebForm 应用程序,它允许用户登录并安排一个活动。事件处理由我为其编写 Windows 服务的本地 Windows 服务器处理和分派。

一切正常,除了我有一些从东海岸登录的客户和一些从西海岸登录的客户。

有人可以建议我如何处理时区差异的可能工作流程吗?时区信息已经与每个客户端一起存储在数据库中。我只是对如何应用时区信息感到困惑。

我知道DateTime有一种ToUniversalTime()方法,但它让我对它的工作原理感到困惑,因为它似乎需要知道DateTime结构所在的时区才能将其转换为通用时间,据我所知,DateTime结构确实结构中没有内置时区信息。

有人可以向我解释一下吗?

4

3 回答 3

1

如果事件计划发生一次DateTimeOffset,则将其存储为UTC 或 UTC是有意义的DateTime。如果您将其存储为DateTimeOffset,您仍然可以将其显示给具有相关偏移量的用户 - 实际上您可以将其显示为其他时区的人,或者作为他们的本地时间,或者作为原始用户的本地时间,并带有它的指示符与观众的当地时间不一样(如果你明白我的意思)。

如果它是经常性的(例如“每天凌晨 4 点”),那么这还不够,因为它不会考虑 DST 的变化。相反,您应该存储本地时间和时区标识符。见TimeZoneInfo.IdTimeZoneInfo.FindSystemTimeZoneById

作为一个公然的插件,您可能希望考虑使用Noda Time API 作为内置类型的更具表现力的替代方案......

您几乎肯定应该使用DateTime.ToUniversalTime(),因为它使用系统时区(即在您的服务器上),这几乎肯定是无关紧要的。

于 2012-11-01T15:17:33.660 回答
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())) 
于 2012-11-01T15:36:12.203 回答
0

来自MSDN

ToUniversalTime 方法将 DateTime 值从本地时间转换为 UTC。要将非本地时区的时间转换为 UTC,请使用 TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) 方法。要转换与 UTC 的偏移量已知的时间,请使用 ToUniversalTime 方法。

从 .NET Framework 2.0 版开始,ToUniversalTime 方法返回的值由当前 DateTime 对象的 Kind 属性确定。

DateTime的默认值Kind未指定,因此您的日期将被假定为本地时间。

于 2012-11-01T15:18:24.167 回答