【问题标题】:Managing timezone & DST issue for javascript application管理 javascript 应用程序的时区和 DST 问题
【发布时间】:2016-02-19 08:22:26
【问题描述】:
我正在尝试创建一个调度应用程序。前端\UI 是使用 JavaScript 开发的。后端是一个使用 MSSQL 服务器作为数据库的 ASP.NET Web Api 应用程序。从 UI 中,用户将安排一个可以每天/每周/每月运行的作业。每个作业最多可以运行 3 个月。该作业将在指定时间在服务器端运行。
假设用户来并选择了一个将在当地时间上午 10 点运行一周(从 11 月 23 日到 11 月 29 日)的作业。在这种情况下,我将从 11 月 23 日开始在数据库中创建七个条目(每天一个)。每行都有开始时间、开始日期和一些与状态相关的列。
我有以下问题:
- 如何在 SQL Server 上存储时间信息(本例中为上午 10 点)?
- 我是否应该在客户端计算机上使用 JavaScript 获取时间,然后将其转换为 UTC?
- 是否应该使用 JavaScript 获取时间并保存用户时区信息?
- DST 相关更改生效后会发生什么情况?
- 像 momemnt.js 这样的库会在这种情况下提供帮助吗?
我正在考虑保存用户时区信息并在服务器上保存他的本地时间。
【问题讨论】:
标签:
javascript
c#
sql-server
timezone
timestamp-with-timezone
【解决方案1】:
警告 - 正确安排时间很困难。还有很多要考虑的。请阅读this 和this。您的大部分问题都在那里得到解决(尽管从其他语言的角度来看,挑战是相同的)。
你也可以看看Quartz.net,这对于很多场景来说已经足够了。
回答您的具体问题:
- 如何在 SQL Server 上存储时间信息(本例中为上午 10 点)?
对于重复规则,存储事件的本地时间。 SQL Server 有一个time 类型,可以很好地存储一天中的时间。您将需要其他字段来跟踪时区、开始日期、星期几和其他模式信息。
对于计划运行的特定实例,您可以根据重复规则中的所有信息计算 UTC datetime。至少,您安排 下一次 发生,并在每次运行后重新计算。在某些情况下,您可能决定预测接下来的 N 次出现,具体取决于您需要向用户显示的内容。 (您也可以为此使用datetimeoffset。请参阅datetime vs datetimeoffset。)
- 我是否应该在客户端计算机上使用 JavaScript 获取时间,然后将其转换为 UTC?
- 是否应该使用 JavaScript 获取时间并保存用户时区信息?
要回答这两个问题:对于安排,您不应丢弃原始输入,该输入将位于安排活动的当地时区。这可能与用户的时区匹配,也可能不匹配。您需要要求用户选择活动的时区。
- DST 相关更改生效后会发生什么情况?
这取决于你。您需要对此进行彻底测试。一般来说,有一段本地时间被跳过,一段本地时间被重复。
当它被跳过时,您必须决定何时运行该事件。选项包括:1)在跳过的时间之前,2)在跳过的时间之后,以及 3)根本不。在大多数情况下,首选选项是在跳过的时间之后运行,方法是将本地时间提前 DST 偏差(通常为 1 小时)。例如,计划在太平洋时间每天 2:30 运行的每日活动将在春季过渡当天的 3:30 运行。
-
当它重复时,您必须决定何时运行该事件。选项包括:1) 在第一次出现时,2) 在第二次出现时,以及 3) 在两次出现时。在大多数情况下,首选选项是仅在 first 出现时运行。例如,计划在太平洋时间每天 1:30 运行的每日活动将在太平洋标准时间 1:30 运行,而不是太平洋标准时间 1:30。
- 这方面的例外情况包括处理营业到深夜并选择在重复时间营业的企业。例如,酒吧、餐厅或电影院。它高度依赖于特定用例和特定业务的选择。
- moment.js 之类的库会在这种情况下提供帮助吗?
不是从调度的角度来看,不是。不过,它可以帮助解析、格式化和验证输入。您也可以使用moment-timezone 来帮助选择活动的时区。如果您在后端使用 node.js 运行它,那么也许会有更多好处。
最大的挑战实际上是一个你没有谈到的挑战,那就是在你的服务器上维护时区数据。在您的 C# 代码中,我建议为此使用 Noda Time,而不是 TimeZoneInfo。然后您可以根据需要update the tzdb data yourself。您还需要考虑重新安排每次发生的 UTC 时刻的工作流程,以防时区更改其偏移量或夏令时日期。