我们的一位程序员决定在MySQL数据库中使用DATE字段来实现这一目标。 发送和保存JS日期对象确实很有效,直到夏令时更改干预(带有令人讨厌的效果:))。 当然,在DATETIME字段中保存日期可以解决问题,但是每个人都会在自己的时区中看到时间/日期。 我们需要每个人(在整个时区)看到同一个日期!
我澄清一下,以获得正确的答案:
我想在MySQL中继续使用DATE字段存储类型(与DATETIME相比 - 确定,可能过多的优化,但它已经存在,我想要一个长期的解决方案,当我从其他开发人员那里收到这样的结构/代码时)
发送本地时间(浏览器中的本地JS)23-05-2016,将以22-05-2016 0X:X0:00Z(UTC)的形式到达服务器并存储。因为它是DATE字段,所以存储的值将仅为22-05-2016。而你失去了一天! :)
我们的解决方案不仅修复了DATE场地修剪,而且还增加了人们现在可以看到相同的正确日期(23-05-2016)这一事实,无论他们在哪个时区!
我喜欢结果,并希望看到一些更好的解决方案来实现同样的目标并改进系统。
实际上,我们只有在夏令时发生变化时才注意到这个问题,所以我的解决方案(如下面的答案)也是一个很好的解决方案。它只消耗客户端的资源。
我已将自己的解决方案发布到这个问题上作为答案。
看到更好的解决方案真的很酷!
答案 0 :(得分:1)
以ISO格式保存日期(包括时区信息),并使用moment.js
将日期时间转换为其他时区。
如果moment.js
不是依赖项,并且您想避免使用额外的库,请继续阅读。
当您写数据(在流程中丢失时区信息)时,不要解决此问题,而是在读取数据库时解决此问题。
在SELECT
查询中,使用convert_tz
内置函数将所有DATETIME
值规范化为您的首选时区。
答案 1 :(得分:0)
MomentJs是你最好的选择。找到你想要的时区并将ISO字符串传递给它,你应该很高兴。 http://momentjs.com/timezone/docs/#/using-timezones/
答案 2 :(得分:0)
有更多的解决方案,但我能想到的最快和最简单的方法如下所示:
让我们尽早介入信息流。 只需在通过AJAX传输数据之前更改数据。
我们使用的功能是:
function addTimezoneDiffAnd12HoursToDate(date) {
var timezoneOffset = date.getTimezoneOffset();
date.setHours(12-Math.floor(timezoneOffset/60));
date.setMinutes(-timezoneOffset % 60);
return date;
}
它的作用是将日期转换为始终在中午(12:00) UTC !
你可以像这样使用它:
$scope.contract.contractDate = addTimezoneDiffAnd12HoursToDate($scope.contract.contractDate);
并将其发送到DATE字段中。
如果您有更简单的解决方案,请告诉我。我想看到它。
答案 3 :(得分:0)
DATE
只是一年,一个月和一天。它没有时间或时区。想想你的生日或结婚日期,或今天的约会。
JS Date
对象根本不是这个。这是一个时间戳。它是自1970年1月1日午夜以来经过的毫秒数。
您应该尽可能将日期保留为日期。使用ISO-8601仅限日期格式,即YYYY-MM-DD
。如果你必须为它分配时间和时区,那么在你做的时候要非常小心。
如果您只是在当地时间午夜分配,那么您将面临失去一天的风险(如您所示),并且您并未考虑在某些时区有当地日子,午夜不存在! (比如巴西的春天)。中午比午夜更安全,但你应该谨慎使用。更好的方法是将日期保留为日期,而不是日期时间。
另外,如果可以的话,我会用代码回答,但是你没有在你的问题中提供任何代码来显示被破坏的内容。请阅读How do I ask a good question?和How to create a Minimal, Complete, and Verifiable example。感谢。