我正在开发一个只在单个时区使用的系统,但它与其他以UTC显示日期和时间的系统集成,所以我们认为我们也一直采用UTC。我们以前也听说过,无论如何,将时间存储在UTC中是可行的,所以这是将麻烦降至最低的最简单方法。
不过最近我们遇到了一些麻烦。我们在系统中记录对用户有价值的事件,所以我们让用户搜索和查看它们。瑞典处于+1时区,因此当地时间0900的事件将存储为0800 UTC时间。当向用户显示事件时,我们可以成功地将其转换回当地时间,直到最近夏令时开始生效。将0800 UTC转换为当地时间现在将增加2小时。记录的事件现在似乎发生在10:00。我该如何处理?
在这种情况下,如果存储的时间与实际保存到DB的时间相同,我可以查看日期并根据DST在特定时间是打开还是关闭来调整它。然而,我认为我需要一个通用的解决方案,因为系统中会在不同的时间(在其他地方)创建时间戳,需要表示未来和过去的时间点。在我看来,我有两个选择。
- 回到存储本地时间,当我与使用UTC的其他系统集成时,只需做一些额外的工作
- 与每个UTC时间戳一起存储一些数据,这些数据可以告诉我是否在夏令时期间创建了时间戳
我错了吗?正确的错过了什么?
您总是可以使用getTimezoneOffset
方法获取客户端时区偏移量。现在剩下的就是将这个时区偏移应用于存储在数据库中的UTC日期,并向最终用户显示正确的日期。另一方面,如果您需要显示用户在数据库中记录事件时使用的时区偏移量,那么您肯定会在数据库中添加一列来记录此偏移量。当你想处理多个时区时,事情会变得棘手:当你想向印度用户显示瑞典用户提交的记录时会发生什么?
您缺少的主要内容是,您不能只将瑞典视为+1时区。时区和时区偏移是两种截然不同的东西。请阅读时区标记wiki以了解更多详细信息。
相反,您可以采取以下两种方法之一:
-
根据它的IANA tzdb标识符来考虑时区。对于瑞典,请使用
Europe/Stockholm
。使用此时区,使用实现tz数据库的语言、库或平台,在UTC和当地时间之间进行转换。 -
与其弄清楚客户端时区是什么,不如依靠客户端操作系统将其转换为本地时间。大多数环境(包括web浏览器中的JavaScript)都可以从UTC转换为本地时间,反之亦然。使用这种方法,只在客户端和服务器之间传输UTC时间。
此外,你没有问这个问题,但在标题中你提到了未来事件。这是一个非常不同的场景,通常需要捕获本地时间和IANA时区。有关详细信息,请参阅此答案。
您也可以阅读夏令时和时区最佳实践。