我理解最好的做法是将UTC日期/时间存储在我们的数据库中,并以其本地时区显示给用户。我们将存储时区而不是偏移量,这样我们就可以支持夏令时。
处理时区的最佳方式是什么?
选项1:服务器只使用UTC,客户端转换为时区
所有以HTML形式发送给浏览器的日期都是UTC格式。客户端将使用moment.js或类似程序将UTC时间转换为正确的时区。将使用数据库中指定的时区,而不是浏览器的本地时间,因为这可能不正确。
当用户提交日期或时间时,在提交给服务器之前必须首先将其转换为UTC时间。
选项2:服务器转换为时区
所有的计算仍然在UTC中进行,日期/时间在最后可能的时刻被转换为正确的时区,例如在HTML中输出日期时。
当客户端提交任何日期/时间时,应立即转换为UTC。
还有别的办法吗?
两种方法都是有效的,但是每种方法都有优缺点。有几件事需要考虑:
-
JavaScript的本地时区转换仅限于它所运行的机器的本地时区,而且它也严重损坏。如果您计划在客户机中转换值,您将需要这里列出的时区库之一。我个人推荐moment-timezone。
-
在客户端(使用任何库)中转换值将需要时区数据,如果您想要支持世界上所有的时区,那么时区数据可能会有些大。您可能需要考虑将数据限制为满足您需求的最小子集。
-
服务器端时区转换也需要有效的时区数据。PHP内置了这个功能,你可以随时了解PECL中timezonedb包的最新更新。
-
你还用ASP.Net标记了你的问题。net包括
TimeZoneInfo
,它只提供对微软时区的支持。如果需要标准的IANA时区(如PHP中使用的时区),则需要一个库。我推荐野田时间。您可以在时区标签wiki中阅读更多关于不同时区的信息。 -
如何交付最终结果取决于您正在编写的应用程序类型。
-
如果您正在创建一个"传统的";web页面,其中HTML是在服务器端呈现的,那么您将呈现一个人类可读的字符串。这意味着不仅要了解时区,还要了解用户的区域设置,以便您可以使用符合文化的格式。
这与时区完全无关。例如,您可能是一个使用MM/DD/YYYY格式的美国人,但您的物理位置仍然位于欧洲并使用欧洲时区。
-
如果你的服务器通过API(即JSON, XML等)交付结果,那么你的结果应该是机器可读的。最好使用ISO 8601格式。具体来说,时间戳应该按照RFC 3339中描述的方式传递。
这意味着它们应该总是包含Z
(对于UTC值)或偏移量(对于本地值)。因此,您可以考虑用户的时区,但是您交付的结果应该包括本地偏移量,以便它是明确的。例如,你有UTC值
2014-07-09T12:00:00Z
,然后在America/Los_Angeles
它是2014-07-09T05:00:00-07:00
,这是应该通过API传递的。在客户端,您可以使用moment.js之类的库为用户呈现该值。例如:
var s = moment.parseZone("2014-07-09T05:00:00-07:00").format("LLL");
相关:如何正确使用时区?