管理 javascript 应用程序的时区和 DST 问题

Managing timezone & DST issue for javascript application

我正在尝试创建一个日程安排应用程序。前面end\UI是用JavaScript开发的。后端是一个 ASP.NET Web Api 应用程序,它使用 MSSQL 服务器作为数据库。从 UI 开始,用户将安排一个可以 运行 daily/weekly/monthly 的作业。每份工作最多可以 运行 3 个月。该作业将在指定时间 运行 在服务器端。

假设用户来选择一份工作,该工作将在当地时间上午 10 点 运行 一周(从 11 月 23 日到 11 月 29 日)。在这种情况下,我将从 11 月 23 日开始在数据库中创建七个条目(每天一个)。每行都有开始时间、开始日期和一些与状态相关的列。

我有以下问题:

  1. 如何在 SQL 服务器上存储时间信息(在本例中为上午 10 点)?
  2. 我应该在客户端计算机上使用 JavaScript 获取时间,然后将其转换为 UTC 吗?
  3. 我是否应该使用 JavaScript 获取时间并保存用户时区信息?
  4. DST 相关更改生效后会发生什么情况?
  5. 像 momemnt.js 这样的库在这种情况下会有帮助吗?

我正在考虑在服务器上保存用户时区信息和他的本地时间。

警告 - 正确安排时间很难。还有很多要考虑的。请阅读this and this。您的大部分问题都在那里得到解决(尽管从其他语言的角度来看,挑战是相同的)。

你也可以看看Quartz.net,很多场景都够用了

回答您的具体问题:

  1. How do I store time information (10 AM in this case) on SQL server?

对于重复规则,存储事件的本地时间。 SQL 服务器有一个 time 类型,可以很好地存储一天中的时间。您将需要其他字段来跟踪时区、开始日期、星期几和其他模式信息。

对于计划到 运行 的特定实例,您根据重复规则中的所有信息计算 UTC datetime。至少,您安排 下一次 发生,并在每次 运行 后重新计算。在某些情况下,您可能决定预测接下来的 N 次事件,具体取决于您需要向用户展示的内容。 (您也可以为此目的使用 datetimeoffset。参见 datetime vs datetimeoffset。)

  1. Should I get the time using JavaScript on client machine and then convert the same to UTC?
  2. Should I get the time using JavaScript and also save the user time zone information?

回答这两个问题:对于日程安排,您不应丢弃原始输入,该输入将位于正在安排的事件的本地时区。这可能与用户的时区匹配,也可能不匹配。您将需要询问用户select事件的时区。

  1. What happens when DST related changes take effect?

这取决于你。您将需要对此进行彻底测试。一般来说,有一段本地时间被跳过,有一段本地时间被重复。

  • 当它被跳过时,你必须决定什么时候运行这个事件。选项包括:1) 在跳过的时间之前,2) 在跳过的时间之后,以及 3) 根本没有。在大多数情况下,首选选项是在跳过的时间之后 运行,方法是将当地时间提前 DST 偏差(通常为 1 小时)。例如,计划在太平洋时间每天 运行 2:30 的每日事件将在 spring 向前过渡的当天 运行 在 3:30。

  • 当它重复时,你必须决定什么时候运行事件。选项包括:1) 在第一次出现时,2) 在第二次出现时,以及 3) 在两次出现时。在大多数情况下,首选选项是仅在 第一次 出现时 运行。例如,计划在太平洋时间每天 1:30 运行 的每日活动将在 1:30 PDT 运行,而不是 1:30 PST。

    • 例外情况包括处理营业至深夜并选择在重复的时间保持营业的企业。例如,酒吧、餐厅或电影院。它高度依赖于特定的用例和特定业务所做的选择。
  1. Will library like moment.js will help in this scenario?

不是从日程安排的角度来看,不是。不过,它可以帮助解析、格式化和验证输入。您还可以使用 moment-timezone 来帮助 select 设置活动的时区。如果您在后端 运行 将其与 node.js 结合使用,那么可能会有更多好处。


最大的挑战其实是你没有提到的,那就是在你的服务器上维护时区数据。在您的 C# 代码中,我建议根据需要使用 Noda Time for this, instead of TimeZoneInfo. You can then update the tzdb data yourself。您还需要考虑重新安排每次出现的 UTC 时刻的工作流程,以防时区更改了其偏移量或夏令时日期。