如何忽略用户的时区并强制 Date() 使用特定时区 [英] How to ignore user's time zone and force Date() use specific time zone
问题描述
在一个 JS 应用程序中,我从服务器 (Ajax) 收到时间戳(例如 1270544790922
).
In an JS app, I receive timestamp (eq. 1270544790922
) from server (Ajax).
基于该时间戳,我使用以下方法创建 Date
对象:
Basing on that timestamp I create Date
object using:
var _date = new Date();
_date.setTime(1270544790922);
现在,_date
解码当前用户区域设置时区的时间戳.我不想那样.
Now, _date
decoded timestamp in current user locale time zone. I don't want that.
我希望 _date
将此时间戳转换为欧洲赫尔辛基市的当前时间(不考虑用户的当前时区).
I would like _date
to convert this timestamp to current time in city of Helsinki in Europe (disregarding current time zone of the user).
我该怎么做?
推荐答案
Date 对象的基础值实际上是 UTC.为了证明这一点,请注意,如果您键入 new Date(0)
,您将看到类似以下内容:Wed Dec 31 1969 16:00:00 GMT-0800 (PST)
.0 在 GMT 中被视为 0,但 .toString()
方法显示的是当地时间.
A Date object's underlying value is actually in UTC. To prove this, notice that if you type new Date(0)
you'll see something like: Wed Dec 31 1969 16:00:00 GMT-0800 (PST)
. 0 is treated as 0 in GMT, but .toString()
method shows the local time.
重要提示,UTC 代表通用时间码.现在两个不同地方的当前时间是相同的 UTC,但输出的格式可以不同.
Big note, UTC stands for Universal time code. The current time right now in 2 different places is the same UTC, but the output can be formatted differently.
这里我们需要的是一些格式
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"
这有效,但是....您不能真正使用任何其他日期方法来达到您的目的,因为它们描述了用户的时区.您想要的是与赫尔辛基时区相关的日期对象.此时您的选择是使用一些 3rd 方库(我推荐这个),或者修改日期对象以便您可以使用它的大部分方法.
This works but.... you can't really use any of the other date methods for your purposes since they describe the user's timezone. What you want is a date object that's related to the Helsinki timezone. Your options at this point are to use some 3rd party library (I recommend this), or hack-up the date object so you can use most of it's methods.
选项 1 - 像moment-timezone这样的第三者
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
这看起来比我们接下来要做的要优雅得多.
This looks a lot more elegant than what we're about to do next.
选项 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)
它仍然认为它是 GMT-0700 (PDT),但如果您不仔细看,您可能会将其误认为是对您的目的有用的日期对象.
It still thinks it's GMT-0700 (PDT), but if you don't stare too hard you may be able to mistake that for a date object that's useful for your purposes.
我很方便地跳过了一部分.您需要能够定义 currentHelsinkiOffset
.如果您可以在服务器端使用 date.getTimezoneOffset()
,或者仅使用一些 if 语句来描述时区更改的时间,那应该可以解决您的问题.
I conveniently skipped a part. You need to be able to define currentHelsinkiOffset
. If you can use date.getTimezoneOffset()
on the server side, or just use some if statements to describe when the time zone changes will occur, that should solve your problem.
结论 - 我认为特别是为了这个目的,你应该使用像 moment-timezone 这样的日期库.
Conclusion - I think especially for this purpose you should use a date library like moment-timezone.
这篇关于如何忽略用户的时区并强制 Date() 使用特定时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!