如何处理具有重复事件的事件调度应用程序中的时区?

How to deal with timezones in an event scheduling application with recurring events?

我正在尝试实施一个事件安排,允许用户 select 工作日以及开始和结束时间。我遇到与时区相关的问题。 这是我的 table(重要的专栏):

create table event (
  id                int not null auto_increment,
  name              varchar(100) not null,
  repeat_event      tinyint(1) default null,
  every_sunday      tinyint(1) default null,
  every_monday      tinyint(1) default null,
  every_tuesday     tinyint(1) default null,
  every_wednesday   tinyint(1) default null,
  every_thursday    tinyint(1) default null,
  every_friday      tinyint(1) default null,
  every_saturday    tinyint(1) default null,
  start_time        time null default null,
  end_time          time null default null,
  start_date        datetime null default null,
  end_date          datetime null default null,
)

应用程序有两种类型的事件调度:周期性和非周期性(根据 repeat_event 列中的值 1 或 0)。 另一个进程负责读取当天的所有事件并通知用户事件开始或结束(我使用 javascript setTimeout 函数来通知 - 用当前日期毫秒减去 start_date 毫秒)。

当repeat_event为0时,我使用start_date和end_date来存储事件日期。在这种情况下,使用日期时间列(没有时区信息)。我在这里没有问题,因为用户会同时收到通知,与时区无关。我以用户时区显示事件日期。

当 repeat_event 为 1 时,我使用 every_*** 列,start_time 和 end_time 来存储事件的工作日和时间。

问题
如何将重复出现的信息存储在数据库中? 例如:如果我将活动安排在 GMT-03:00 的 22:00 - 23:00 星期六。这不是 UTC 中的星期六,因此列 every_saturday 存储在 "wrong" 中。 我应该使用用户时区存储此信息吗?

当涉及到未来的计划时,尤其是 对于重复发生的事件,您不应该按照 UTC 存储值。相反,您需要根据与该事件相关的时区来存储值,并且您还需要存储该时区的标识符(例如 "America/Los_Angeles"

为了方便地对这些事件进行排序,您可以额外计算事件 发生 的 UTC 时间,但您应该准备好重新计算它 - 作为时间规则区域经常变化。下一个事件发生的 UTC 时间应该在另一列中,或者完全是另一个 table。

请记住,安排未来的活动是一个困难的问题。要正确执行此操作涉及多个部分。您不应该寻找一个简单的解决方案。请阅读我写的关于这个主题的其他一些帖子:here, and here