长话短说,我们开发了一个供内部使用的 Web 应用程序,一件事引发了另一件事,现在它是一个拥有 1,000 多个用户的 SaaS。问题在于,所有与日期相关的内容(很多!)都被硬编码为太平洋时间(不要问),并且用户显然想要自己的时区。
我已经阅读了在网络应用程序中管理时区的最佳方法,但仍然不确定我们现有的、实时的、关键任务网络应用程序的最佳方法,该应用程序已被超过 1,000 家企业使用...
我想最大的“问题”只是我们正在谈论 10 万多行代码,并且可能至少有 100 个与日期相关的不同数据库查询。
根据我的阅读,管理时区的“正确”方法似乎是将所有内容存储在 UTC 中,然后在输出时转换为用户 TZ ...
但是在这一点上,简单地修改所有与日期相关的查询并基本上使用MySQL的convert_tz包装所有日期以从现有的PDT时间戳转换为用户的时区会有什么问题吗?
据我所知,如果我们将数据库中的所有日期字段转换为 UTC 并将 MySQL 更改为在 UTC 下运行,我们无论如何都必须做同样的事情,那么是否有任何特殊原因来转换所有现有的日期字段此时日期字段是否已转换为 UTC?
请您参考如下方法:
嗯,“正确”在很大程度上取决于您的应用程序的用途以及应用程序中的日期的用途。在许多场景中,存储为 UTC 并转换为用户的时区正是所需要的。但不是全部。
例如,如果您的日期是安排 future 事件的重复模式的一部分,那么您不会为此使用 UTC。
再举一个例子,如果您有仅限日期的字段,那么这些日期可能是“工作日”,它可能基于用户的时区,但也可能基于您企业的时区。
存储为 UTC 的最常见情况是当您指的是明确的时刻时,例如存储实际发生的事情的时间戳(过去时)。
那么回到你的问题 - 为什么不直接以太平洋时间为基础呢?嗯,太平洋时间并不像 UTC 那样固定。冬季 PST 期间为 UTC-8,夏季 PDT 期间为 UTC-7。因此,每年都会有一小时的本地时间缺失和一小时的重叠,其中本地时间会重复。您可以在the daylight saving time tag wiki中阅读更多相关信息。 .
我建议您采取以下方法:
- 在数据库表中为 UTC 时间创建一个新列
- 编写一些代码将本地时间调整为 UTC。使用夏令时转换 shown here确定是否添加 8 小时或 7 小时来计算 UTC 时间。将调整后的值复制到新字段。
- 手动重新访问属于后备重叠的值。对于太平洋时间,该时间介于 DST 结束日期的
1:00:00.000
和1:59:59.999
之间。您可能需要手动调整这些值,因为它们可能属于 PDT 或 PST。为了消除歧义,请查看是否还有其他值需要考虑。例如,如果您有一个自动递增主键,那么当按该键排序时,时间戳应该大致是连续的。 - 现在您已经有了 UTC 的新列,开始转换所有代码以使用它。
- 最终,您可以删除旧列。