服务器或客户端在发送/接收日期时应该处理时区吗?
Posted
技术标签:
【中文标题】服务器或客户端在发送/接收日期时应该处理时区吗?【英文标题】:Should the Server or the Client handle timezone when sending/receiving dates? 【发布时间】:2014-08-30 14:06:10 【问题描述】:我了解最佳做法是将 UTC 日期/时间存储在我们的数据库中,并以当地时区显示给用户。我们将存储时区而不是偏移量,以便支持夏令时。
哪种方式最适合处理时区?
选项 1:服务器仅使用 UTC,客户端转换为时区
以 html 格式发送到浏览器的所有日期均采用 UTC。客户端将使用 moment.js 或类似文件将 UTC 时间转换为正确的时区。将使用我们数据库中指定的时区而不是浏览器的本地时间,因为这可能不正确。
用户提交日期或时间时,必须先转换为UTC时间,然后再提交给服务器。
选项 2:服务器转换为时区
所有计算仍以 UTC 进行,并且在可能的最后一刻将日期/时间转换为正确的时区,例如在以 HTML 格式输出日期时。
当客户端提交任何日期/时间时,应立即转换为 UTC。
还有其他方法吗?
【问题讨论】:
您应该始终从htaccess
或从服务器php.ini
设置UTC
。此外,在数据库中,日期应为UTC
。这样所有的日期都是一样的。您可以使用mysql
和PHP
来操作日期而无需转换。唯一的转化发生在您向用户列出日期时。
@machineaddict 我在问在客户端或服务器端转换日期是否是最佳做法。即我们是让服务器只说 UTC 还是应该处理时区转换?
根据我上面解释的方法,日期完全从服务器端处理。因此,服务器只在UTC
中交谈。
@machineaddict 如果服务器只以 UTC 进行通信,那么我们依赖 javascript 在页面加载时更改日期字符串?
如果您的用户已注册,他们可以选择他们的时区。如果用户是客人,您可以使用 javascript 更改日期以对应他们的计算机时区,显示服务器时区,或者您可以从他们的 ip 猜测他们的时区。一个想法是看看像vBulettin
或phpBB
这样的脚本如何根据用户状态(访客/登录)处理他们的时间。我的下一个项目必须是这样,所以我可能会在其中实现您的最佳答案。
【参考方案1】:
任何一个选项都有效,但每种方法都有优点和缺点。有几件事情需要考虑:
JavaScript 的原生时区转换仅限于运行它的机器的本地时区,也是seriously broken。如果您打算在客户端中转换值,则需要one of the time zone libraries listed here。我个人推荐moment-timezone。
在客户端(使用任何库)中转换值将需要时区数据,如果您想支持世界上所有的时区,这可能会有点大。您可能需要考虑将数据限制为满足您要求的最小子集。
服务器端时区转换也需要有效的时区数据。 PHP 已内置此功能,您可以随时了解the timezonedb package in PECL 的更新。
您还使用 ASP.Net 标记了您的问题。 .Net 包括TimeZoneInfo
,它仅提供对 Microsoft 时区的支持。如果您想要标准 IANA 时区(如 PHP 中使用的时区),那么您将需要一个库。我推荐Noda Time。您可以在the timezone tag wiki 中阅读有关不同类型时区的更多信息。
如何交付最终结果取决于您编写的应用程序类型。
如果您正在创建一个“传统”网页,其中 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");
相关:How to properly work with Timezone?
【讨论】:
以上是关于服务器或客户端在发送/接收日期时应该处理时区吗?的主要内容,如果未能解决你的问题,请参考以下文章