时区转换和夏令时
Posted
技术标签:
【中文标题】时区转换和夏令时【英文标题】:Timezone conversion and daylight saving 【发布时间】:2012-10-31 22:25:42 【问题描述】:我们有一个调度程序应用程序。使用此应用程序,用户可以安排任务在接下来的 30 天内每天上午 8 点(太平洋标准时间)运行。我们将时间转换为 UTC 并将其存储在数据库中,因为我们有来自不同时区的用户。我们使用以下函数将时间转换为 UTC:
public static DateTime ToAccountLocalTime(this DateTime dt)
return TimeZoneInfo.ConvertTimeFromUtc(dt, TimeZoneInfo.FindSystemTimeZoneById("user time zone"));
现在,如果用户计划在 2012 年 11 月 1 日之后的 30 天每天上午 8 点运行任务,则在数据库中为这 30 天的每一天创建 30 个条目,时间设置为 UTC 下午 4 点(返回上述方法)。
问题发生在 11 月 4 日夏令时结束时。该任务在早上 7 点而不是早上 8 点开始运行,因为调度程序服务始终根据 UTC 运行。
为了解决这个问题,我们需要上述方法返回 11 月 1 日至 11 月 3 日的 UTC 下午 4 点和 11 月 4 日之后的 UTC 下午 3 点。我应该进行哪些更改来实现这一点?
【问题讨论】:
请查看有关 ConvertTimeFromUtc 的 MSDN 库文章。请注意它如何使用 IsDaylightSavingTime()。 您应该考虑到夏令时在全球范围内的应用方式不同。我发现this link 列出了一些应用夏令时的方式。以 UTC 存储您的时间将使时间标准化,但我认为您不能标准化夏令时。 考虑使用野田时间:code.google.com/p/noda-time @HansPassant 我找不到这篇文章。能给个链接吗? @Francois 我知道这一点,因此我想知道解决问题的正确方法是什么 【参考方案1】:如果本地时间很重要,我会存储本地时间 + 时区,并在需要 UTC 时将其转换为 UTC。
然后您存储太平洋时间上午 8 点,它将根据当前是否为 DST 转换为下午 3 点或 4 点 UTC。
您将遇到的问题取决于您的数据库,它可能不支持时区。我可能会将您传递的字符串存储到FindSystemTimeZoneById
。如果您想变得花哨,可以制作一个表格,列出所有具有标识列的人并存储 Id。
【讨论】:
【参考方案2】:您需要在 30 天中的每一天都进行转换,因此请为 localDate.AddDays(n)
、n
= 1
..30
,并存储这些结果。
如果ToUtc
的定义类似于:
return TimeZoneInfo.ConvertTimeToUtc(dt, TimeZoneInfo.FindSystemTimeZoneById("user time zone"));
它应该在指定的时间迎合 DST。 (注意不明确或无效时间的例外情况。)
【讨论】:
以上是关于时区转换和夏令时的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Dynamics CRM 中获取时区的夏令时开始和结束?