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