我应该如何在服务器端存储来自JS的时间戳,以便我可以可靠地使用它转换为其他时区?

How should I store a timestamp coming from JS on the server-side in a way that I can reliably use to convert to other timezones?

本文关键字:我可以 时区 其他 转换 服务器端 存储 时间戳 JS 我应该      更新时间:2023-09-26

我有一个网站,在那里我设置了一个位于美国西部的水疗中心预约,例如太平洋标准时间。

当用户选择一个时间点,比如说,2010年3月20日上午10点,从我的桌面使用EDT时间的客户端创建的日期对象是:


时间戳:1395324000000utc string: 2014-03-20 10:00:00 GMT-0400 (EDT)

我需要将其存储在服务器端。目前,我通过XHR将时间戳从JS传递到PHP,并除以1000:

ajax url: ajax.php?时间戳= 1395324000000
php代码:

$time = $_GET['timestamp'] / 1000;

因为我的默认时区被手动设置为America/New_York,并且我的客户端时间是EDT,所以它们是一致的,因此显示正确的时间:

echo date('M d Y H:i:s', $time); // Mar 20 2014 10:00:00

但是理想情况下,我认为我应该将服务器端的日期时间设置为America/los angeles ..然而,这将使echo date显示错误的日期,因为它将是PST而不是EDT:

date_default_timezone_set('America/Los_Angeles');
Mar 20 2014 07:00:00

当用户最初选择10:00 AM时,现在变成了7:00 AM,这显然会导致混乱…如果用户选择了10:00 AM,我需要它是10:00 AM。

我的另一个担心是,如果用户的客户端时间不是EDT时间怎么办?难道它不符合America/New_YorkAmerica/Los_Angeles吗?

我是否应该做一些事情,比如通过Javascript中的.toUTCString保存UTC字符串,然后在UTC中存储时间,并设置默认时区为UTC,然后在我需要显示PST时间时将其转换为PST时间?

顺便说一下,我不能使用DateTimeZoneDateTime,因为我正在处理php <5.3

我已经完成了这个约会。

我的解决方案是(如你所建议的)将所有内容存储为UTC,并在需要时将其转换为用户的时区。

我用date.js: http://www.datejs.com/做了主要的JS编码。

将UTC日期从服务器转换为本地用户

var d = new Date();
var offset = d.getTimezoneOffset();
var hours =  parseInt(offset / -60);
var minutes = (offset % 60) * -1;
appointment_date = Date.parse(utc_date).add({minutes: minutes, hours:hours})

当然,utc_date必须是正确的格式-但使用date_format mysql函数应该很容易。

我总是将UTC日期和用户版本的日期存储在数据库中-所以当我给他们发邮件时,我不必根据他们的TZ

进行计算。
appointment_id   utc_date           user_date
1                2011-10-01 10:00   2011-10-01 16:00

我相信你已经明白了。

您应该始终将时间戳存储在服务器上。唯一需要关心时区的情况是,当在字符串中输入或输出日期时,首先调用date_default_timezone_set,其中包含输入日期(或将要输出日期)所在的时区

如果需要在服务器上创建时间字符串(或解析),则需要找到客户端时区偏移量并相应地进行调整。

如果您在客户端使用JS显示时间,时间将自动以当地时区显示/输入。没有办法告诉浏览器使用不同的时区。您只能使用本地时区(默认)或调用getUTCxxxx方法来获取GMT时间并自己调整它(如果您知道要显示它的时区偏移量)。无论在哪个时区,时间戳都是相同的。

真正的问题是当你需要夏令时的帐户。这是另一个大问题

请记住,此建议仅针对Microsoft web服务和生成的代理进行了测试,可能不适用于其他安排。

我发现日期时间值是由JS在浏览器的时区中解释的。

在下面的示例中,boundsResult是web方法调用的成功处理程序接收到的数据集。START和END是离开服务器为UTC的日期时间值。

var offset_milliseconds = boundsResult[0].START.getTimezoneOffset() * 60000;
var startTime = new Date(boundsResult[0].START.getTime() - offset_milliseconds);
var endTime = new Date(boundsResult[0].END.getTime() - offset_milliseconds);

此修复依赖于始终以UTC离开服务器的值。这不是一个不合理的期望;通用时间框架是处理多个客户端时区的唯一直接方法。存储本地化的值是自找麻烦。

无论出于何种原因,另一种转换方式似乎是自动的。

你可以这样写:

function utcDate(date) {
  return new Date(date.getTime() - 60000 * date.getTimezoneOffset());
}

然后样本看起来像这样

var startTime = utcDate(boundsResult[0].START);
var endTime = utcDate(boundsResult[0].END);