JavaScript:如何设置一个日期,使其在世界各地看起来都一样



我们的一位程序员决定在MySQL数据库中使用DATE字段来实现这一点。在夏令时更改介入之前,发送和保存JS日期对象的工作一直很好(效果很糟糕:)。当然,将日期保存在DATETIME字段中可以解决问题,但每个人都可以在自己的时区中看到时间/日期。我们需要每个人(所有时区)看到相同的日期!


我澄清了这一点,以获得正确的答案:

我想继续在MySQL中使用DATE字段存储类型(与DATETIME相比,好吧,可能太优化了,但它已经存在了,当我从其他开发人员那里收到这样的结构/代码时,我想要一个长期的解决方案)

发送本地时间(浏览器中的本地JS)23-05-2016,将于22-05-2016 0X:X0:00Z(UTC)到达服务器并存储。因为它是一个DATE字段,所以存储的值将仅变为2016年5月22日。你失去了一天!:)

我们下面的解决方案不仅修复了DATE字段的修剪,还增加了一个事实,即人们现在可以看到相同的正确日期(23-05-2016),无论他们在哪个时区!

我喜欢这样的结果,希望看到一些更好的解决方案来实现同样的目标并改进系统。

事实上,我们只有在夏令时改变时才注意到这个问题,所以我的解决方案(如下所示)也是一个很好的解决方案。而且它只消耗客户端的资源。

我已经发布了我自己对这个问题的解决方案作为下面的答案

如果能从你那里看到一个更好的解决方案,那将是非常酷的!

使用Javascript

将日期保存为ISO格式(包括时区信息),然后使用moment.js将日期时间转换为其他时区。

如果moment.js还不是一个依赖项,并且您希望避免额外的库,请继续阅读。

使用MySQL

写入数据(在过程中丢失时区信息)时,不要解决这个问题,而应该在读取数据库时解决这个问题。

SELECT查询中,使用convert_tz内置函数将所有DATETIME值标准化为您喜欢的时区。

MomentJs是您的最佳选择。找到您想要的时区并将ISO字符串传递给它,您就可以出发了。http://momentjs.com/timezone/docs/#/using-时区/

DATE只是一年、一个月和一天。它没有时间,也没有时区。想想你的生日或结婚日期,或者今天的日期。

JSDate对象根本不是这样的。这是一个时间戳。它是自1970年1月1日午夜UTC以来经过的毫秒数。

只有在可能的情况下,你才应该把约会当作约会。使用ISO-8601日期专用格式,即YYYY-MM-DD。如果你必须给它分配一个时间和时区,那么在这样做的时候要非常小心。

如果你只指定当地时间午夜,那么你就有失去一天的风险(正如你所展示的那样),而且你没有考虑到在一些时区存在不存在午夜的当地日子!(比如巴西的春日)。中午比午夜更安全,但你还是应该谨慎使用。更好的方法是将日期保持为日期,而不是日期时间。

此外,如果可以的话,我会用代码回答,但你的问题中没有提供任何代码来显示损坏的地方。请阅读我该如何问一个好问题?以及如何创建最小、完整和可验证的示例。谢谢

有更多的解决方案,但我能想出的最快、最简单的解决方案如下所述:

让我们尽早介入信息流。在通过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字段中。

如果您有更简单的解决方案,请告诉我。我想看看。

最新更新