我有一个网站,在那里我设置了一个位于美国西部的水疗中心预约,例如太平洋标准时间。
当用户选择一个时间点,比如说,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_York
或America/Los_Angeles
吗?
我是否应该做一些事情,比如通过Javascript中的.toUTCString
保存UTC字符串,然后在UTC中存储时间,并设置默认时区为UTC,然后在我需要显示PST时间时将其转换为PST时间?
顺便说一下,我不能使用DateTimeZone
或DateTime
,因为我正在处理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);