war*_*ech 96 javascript timezone date
在JS应用程序中,我1270544790922
从服务器(Ajax)接收时间戳(eq.).
基于该时间戳我Date
使用以下方法创建对象:
var _date = new Date();
_date.setTime(1270544790922);
Run Code Online (Sandbox Code Playgroud)
现在,_date
解码当前用户区域设置时区中的时间戳.我不希望这样.
我想_ date
将此时间戳转换为欧洲赫尔辛基市的当前时间(忽略用户的当前时区).
我怎样才能做到这一点?
Par*_*ris 61
Date对象的基础值实际上是UTC.为了证明这一点,请注意,如果你输入,new Date(0)
你会看到类似的东西:Wed Dec 31 1969 16:00:00 GMT-0800 (PST)
.在GMT中0被视为0,但是.toString()
方法显示当地时间.
大注释,UTC代表通用时间码.现在在2个不同位置的当前时间是相同的UTC,但输出的格式可以不同.
我们需要的是一些格式化
var _date = new Date(1270544790922);
// outputs > "Tue Apr 06 2010 02:06:30 GMT-0700 (PDT)", for me
_date.toLocaleString('fi-FI', { timeZone: 'Europe/Helsinki' });
// outputs > "6.4.2010 klo 12.06.30"
_date.toLocaleString('en-US', { timeZone: 'Europe/Helsinki' });
// outputs > "4/6/2010, 12:06:30 PM"
Run Code Online (Sandbox Code Playgroud)
这可以工作但是......你不能真正使用任何其他日期方法用于你的目的,因为它们描述了用户的时区.你想要的是一个与赫尔辛基时区相关的约会对象.此时你的选择是使用一些第三方库(我推荐这个),或者破解日期对象,这样你就可以使用它的大部分方法.
选项1 - 像时刻一样的第三方
moment(1270544790922).tz('Europe/Helsinki').format('YYYY-MM-DD HH:mm:ss')
// outputs > 2010-04-06 12:06:30
moment(1270544790922).tz('Europe/Helsinki').hour()
// outputs > 12
Run Code Online (Sandbox Code Playgroud)
这看起来比我们接下来要做的更优雅.
选项2 - 破解日期对象
var currentHelsinkiHoursOffset = 2; // sometimes it is 3
var date = new Date(1270544790922);
var helsenkiOffset = currentHelsinkiHoursOffset*60*60000;
var userOffset = _date.getTimezoneOffset()*60000; // [min*60000 = ms]
var helsenkiTime = new Date(date.getTime()+ helsenkiOffset + userOffset);
// Outputs > Tue Apr 06 2010 12:06:30 GMT-0700 (PDT)
Run Code Online (Sandbox Code Playgroud)
它仍然认为它是GMT-0700(PDT),但如果你不太盯着,你可能会误认为是对你的目的有用的日期对象.
我方便地跳过了一部分.你需要能够定义currentHelsinkiOffset
.如果您可以date.getTimezoneOffset()
在服务器端使用,或者只是使用一些if语句来描述何时会发生时区更改,那么这应该可以解决您的问题.
结论 - 我认为特别是为了这个目的,你应该使用像时刻一样的日期库.
小智 19
要考虑毫秒和用户的时区,请使用以下命令:
var _userOffset = _date.getTimezoneOffset()*60*1000; // user's offset time
var _centralOffset = 6*60*60*1000; // 6 for central time - use whatever you need
_date = new Date(_date.getTime() - _userOffset + _centralOffset); // redefine variable
Run Code Online (Sandbox Code Playgroud)
dhe*_*ran 15
只是另一种方法
function parseTimestamp(timestampStr) {
return new Date(new Date(timestampStr).getTime() + (new Date(timestampStr).getTimezoneOffset() * 60 * 1000));
};
//Sun Jan 01 2017 12:00:00
var timestamp = 1483272000000;
date = parseTimestamp(timestamp);
document.write(date);
Run Code Online (Sandbox Code Playgroud)
干杯!
Tim*_*nen 13
我怀疑,答案没有给出正确的结果.在问题中,提问者想要在Hellsinki中将时间戳从服务器转换为当前时间而忽略用户的当前时区.
事实上,用户的时区可能是我们无法信任的时区.
如果是 时间戳是1270544790922我们有一个功能:
var _date = new Date();
_date.setTime(1270544790922);
var _helsenkiOffset = 2*60*60;//maybe 3
var _userOffset = _date.getTimezoneOffset()*60*60;
var _helsenkiTime = new Date(_date.getTime()+_helsenkiOffset+_userOffset);
Run Code Online (Sandbox Code Playgroud)
当纽约人访问该页面时,警报(_helsenkiTime)打印:
Tue Apr 06 2010 05:21:02 GMT-0400 (EDT)
Run Code Online (Sandbox Code Playgroud)
当芬兰人访问该页面时,警报(_helsenkiTime)打印:
Tue Apr 06 2010 11:55:50 GMT+0300 (EEST)
Run Code Online (Sandbox Code Playgroud)
因此,只有当页面访问者在他的计算机中具有目标时区(欧洲/赫尔辛基)时,该功能才是正确的,但几乎在世界其他任何地方都失败了.并且因为服务器时间戳通常是UNIX时间戳,根据定义为UTC,即自Unix Epoch(1970年1月1日00:00:00 GMT)以来的秒数,我们无法从时间戳确定DST或非DST.
所以解决方案是DISREGARD用户的当前时区,并实现某种方式来计算UTC偏移,无论日期是否在DST.Javascript没有本机方法来确定其他时区的DST转换历史,而不是用户的当前时区.我们可以使用服务器端脚本最简单地实现这一点,因为我们可以使用所有时区的整个转换历史轻松访问服务器的时区数据库.
但是,如果您无法访问服务器(或任何其他服务器)的时区数据库并且时间戳是UTC,则可以通过在Javascript中对DST规则进行硬编码来获得类似的功能.
要涵盖1998年至2099年欧洲/赫尔辛基的日期,您可以使用以下功能(jsfiddled):
function timestampToHellsinki(server_timestamp) {
function pad(num) {
num = num.toString();
if (num.length == 1) return "0" + num;
return num;
}
var _date = new Date();
_date.setTime(server_timestamp);
var _year = _date.getUTCFullYear();
// Return false, if DST rules have been different than nowadays:
if (_year<=1998 && _year>2099) return false;
// Calculate DST start day, it is the last sunday of March
var start_day = (31 - ((((5 * _year) / 4) + 4) % 7));
var SUMMER_start = new Date(Date.UTC(_year, 2, start_day, 1, 0, 0));
// Calculate DST end day, it is the last sunday of October
var end_day = (31 - ((((5 * _year) / 4) + 1) % 7))
var SUMMER_end = new Date(Date.UTC(_year, 9, end_day, 1, 0, 0));
// Check if the time is between SUMMER_start and SUMMER_end
// If the time is in summer, the offset is 2 hours
// else offset is 3 hours
var hellsinkiOffset = 2 * 60 * 60 * 1000;
if (_date > SUMMER_start && _date < SUMMER_end) hellsinkiOffset =
3 * 60 * 60 * 1000;
// Add server timestamp to midnight January 1, 1970
// Add Hellsinki offset to that
_date.setTime(server_timestamp + hellsinkiOffset);
var hellsinkiTime = pad(_date.getUTCDate()) + "." +
pad(_date.getUTCMonth()) + "." + _date.getUTCFullYear() +
" " + pad(_date.getUTCHours()) + ":" +
pad(_date.getUTCMinutes()) + ":" + pad(_date.getUTCSeconds());
return hellsinkiTime;
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
var server_timestamp = 1270544790922;
document.getElementById("time").innerHTML = "The timestamp " +
server_timestamp + " is in Hellsinki " +
timestampToHellsinki(server_timestamp);
server_timestamp = 1349841923 * 1000;
document.getElementById("time").innerHTML += "<br><br>The timestamp " +
server_timestamp + " is in Hellsinki " + timestampToHellsinki(server_timestamp);
var now = new Date();
server_timestamp = now.getTime();
document.getElementById("time").innerHTML += "<br><br>The timestamp is now " +
server_timestamp + " and the current local time in Hellsinki is " +
timestampToHellsinki(server_timestamp);?
Run Code Online (Sandbox Code Playgroud)
无论用户时区如何,都会打印以下内容:
The timestamp 1270544790922 is in Hellsinki 06.03.2010 12:06:30
The timestamp 1349841923000 is in Hellsinki 10.09.2012 07:05:23
The timestamp is now 1349853751034 and the current local time in Hellsinki is 10.09.2012 10:22:31
Run Code Online (Sandbox Code Playgroud)
当然,如果您可以以偏移量(DST或非DST版本)已添加到服务器上的时间戳的形式返回时间戳,则无需在客户端计算它,您可以大量简化该功能.但请记住不要使用timezoneOffset(),因为那时你必须处理用户时区,这不是想要的行为.
归档时间: |
|
查看次数: |
144217 次 |
最近记录: |