简体   繁体   English

在JavaScript中计算两个日期之间的时差时区问题

[英]Timezone Problems when calculating the difference between two Dates in JavaScript

I use the following to calculate the difference between two dates in JavaScript: 我使用以下代码来计算JavaScript中两个日期之间的差:

var dateOne = new Date; // Now
var dateTwo = new Date( dateOne.getTime() + 60 * 1000 ); // Now + One Minute
var difference = new Date( dateTwo - dateOne );

So, logically, difference should be one minute. 因此,从逻辑上讲, difference应为一分钟。 But Firebug tells me that the difference is one hour off, and the timezone somehow also changes! 但是Firebug告诉我,相差一小时,而且时区也有所改变!

 dateOne = Date {Sun Sep 11 2011 01:07:55 GMT+0200 (CET)}
 dateTwo = Date {Sun Sep 11 2011 01:08:55 GMT+0200 (CET)}
 difference = Date {Thu Jan 01 1970 01:01:00 GMT+0100 (CET)}

How can I fix this? 我怎样才能解决这个问题?

Date is designed for storing exact dates and times, not differences between dates and times. Date设计用于存储确切的日期和时间,而不是日期和时间之间的差异。 Subtracting those Date objects yields the number of milliseconds between those two dates. 减去这些Date对象将得出这两个日期之间的毫秒数。 You then create a new Date with that number of milliseconds since the Epoch. 然后,您创建一个新的Date ,该Date自该纪元以来以毫秒为单位。 Since the Epoch is midnight of January 1, 1970, the result will be 12:01 AM of January 1, 1970. Daylight savings time changes the timezone a little. 由于纪元是1970年1月1日午夜,因此结果将是1970年1月1日上午12:01。夏时制会稍微改变时区。

In JavaScript all times are in GMT. 在JavaScript中,所有时间都是格林尼治标准时间(GMT)。 Every time you convert a Date to a string the timezone is "applied" to the output. 每次将Date转换为字符串时,时区将“应用于”输出。 So you can try to get the difference in milliseconds: 因此,您可以尝试获取以毫秒为单位的差异:

difference = dateTwo.getTime() - dateOne.getTime()

That's obviously 60000 since you added that. 自从您添加后,显然是60000。

There is no TimeSpan class or something. 没有TimeSpan类。 Dates only store dates. 日期仅存储日期。

EDIT: 编辑:
If you were wondering why there was the output of +2:00 hours and then just +1:00 that's because January 1st is in Standard Time whereas September 11th has Summer Saving Time. 如果您想知道为什么输出+2:00小时,然后仅输出+1:00,那是因为1月1日是标准时间,而9月11日是夏令时。 It's not because JavaScript does something funny when deducting one date from another. 这不是因为JavaScript从另一个日期中扣除一个日期时会做一些有趣的事情。

The previous answers are very good at clarifying the cause of the problem but I think it also makes sense to point out that Javascript has both "native timezone" and "UTC" methods:- 先前的答案非常善于阐明问题的原因,但我认为指出Javascript同时具有“本地时区”和“ UTC”方法也很有意义:

var dtnow = new Date();
var val1 = dtnow.getHours();
var val2 = dtnow.getUTCHours();

...If the machine running that code has a local timezone other than GMT (perhaps UK Daylight Savings which is GMT+01:00), then the return values could be different (depending on the date value you have set and whether the JS engine does or doesn't return GMT from the non-UTC method - i have seen differences, for example in Rhino there IS a difference). ...如果运行该代码的计算机的本地时区不是格林尼治标准时间(GMT + 01:00,可能是英国夏令时),则返回值可能会有所不同(取决于您设置的日期值以及JS是否引擎通过非UTC方法返回GMT或不返回GMT-我已经看到了差异,例如在Rhino中存在差异)。

Therefore for the purpose of the calculations you MAY wish to extract all values using the UTC methods, which ensures everything is based upon GMT. 因此,出于计算目的,您可能希望使用UTC方法提取所有值,以确保所有内容均基于GMT。 That would make the maths "technically correct", but whether that is semantically correct for the given purpose depends on the use case. 这将使数学“在技术上是正确的”,但是对于给定的目的,这在语义上是否正确取决于用例。

For example, 2am in USA compared to 2am in UK, ignoring timezones, is 0. Whereas with timezones it could be 6 (for example). 例如,美国的凌晨2点与英国的凌晨2点(不考虑时区)相比为0。而对于时区,则为6(例如)。 I sometimes struggle with this too and often have to think hard about what I'm trying to achieve before I following one route or another! 我有时也会为此而挣扎,并且在沿着一条路线或另一条路线前,常常不得不认真思考我要实现的目标! Always bakes my noodle for a little while :-) 总是把面条烤一会儿:-)

you can calculate a full proof days difference between two dates resting across TZs by the following formula: 您可以通过以下公式计算跨TZ休息的两个日期之间的完整证明天差:

 var start = new Date('10/3/2015'); var end = new Date('11/2/2015'); var days = (end - start) / 1000 / 60 / 60 / 24; console.log(days); // actually its 30 ; but due to daylight savings will show 31.0xxx // which you need to offset as below days = days - (end.getTimezoneOffset() - start.getTimezoneOffset()) / (60 * 24); console.log(days); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM