长话短说,我们开发了一个内部使用的web应用程序,一件事接着一件事,现在它是一个拥有超过1000名用户的SaaS。问题是所有与日期相关的东西(很多!)都硬编码为太平洋时间(不要问),用户显然想要自己的时区。
我已经阅读了在web应用程序中管理时区的最佳方法,但仍然不确定我们现有的,实时的,任务关键型web应用程序的最佳方法,被1000多家企业使用…
我猜最大的"问题"在于我们正在谈论的是100k+行代码,并且可能至少有100个不同的数据库查询是与日期相关的。
根据我所读到的,管理时区的"正确"方式似乎是将所有内容存储在UTC中,然后在输出时转换为用户TZ…
但是在这一点上,简单地修改所有与日期相关的查询,基本上用MySQL的convert_tz包装所有日期,从现有的PDT时间戳转换到用户的时区,会有什么问题吗?
据我所知,如果我们将DB中的所有日期字段转换为UTC,并将MySQL更改为在UTC下运行,我们无论如何都必须做同样的事情,那么在这一点上是否有任何特别的理由将所有现有的日期字段转换为UTC ?
嗯,"正确"在很大程度上取决于你的应用程序做什么,以及你的应用程序中的日期是用来做什么的。在许多情况下,存储为UTC并转换为用户的时区正是需要的。但不是全部。
例如,如果您的日期是用于调度未来事件的循环模式的一部分,那么您就不会使用UTC。
作为另一个例子,如果您有日期字段,那么这些日期可能是"工作日",它可能基于用户的时区,但可能基于您的业务时区。
存储为UTC的最常见情况是当你引用一个明确的时间瞬间时,例如存储实际发生时间的时间戳(过去时)。
所以回到你的问题——为什么不把它建立在太平洋时间上呢?嗯,太平洋时间不像UTC时间那样固定。冬季PST时采用UTC-8,夏季PDT时采用UTC-7。正因为如此,每年都会有一个小时的时间差,在这个时间差中,当地时间是缺失的,而在一个小时的重叠中,当地时间是重复的。您可以在日光节约时间标签wiki中了解更多信息。
我建议你采取以下方法:
- 在数据库表中为UTC时间创建一个新列 编写一些代码将本地时间调整为UTC。使用这里显示的夏令时转换来确定是添加8小时还是7小时来计算UTC时间。将调整后的值复制到新字段。
- 手动重新访问落在回退重叠中的值。对于太平洋时间,它位于夏令时结束日期的
1:00:00.000
和1:59:59.999
之间。您可能需要手动调整这些值,因为它们可能属于PDT或PST。要消除歧义,请查看是否需要考虑任何其他值。例如,如果您有一个自动递增的主键,那么当按该键排序时,时间戳应该是大致顺序的。现在你有了UTC的新列,开始转换你所有的代码来使用它。 - 最后,您可以删除旧列。