为什么JavaScript根据结构相同的字符串猜测两个不同的时区?

Tyl*_*sSN 3 javascript datetime date gmt

我以这种格式向我的脚本提供了两个日期:2016-05-25 12:30:02.但是,JavaScript将每个日期设置为不同的GMT偏移量.我在这里格式化了日期以匹配建议的答案,并添加了提供的功能,但我得到了与下面显示的相同的结果,所以我还原回到下面显示的原始脚本.

var response = JSON.parse(jsonResponse);
var lastExportedOrderData = response.lastExportedOrder;

/* currentDateTime = '2016-05-25 12:30:02'; */
var currentDateTime = new Date(response.scriptExecutionTime); 

/* lastOrderExportedAt = '2016-01-12 16:53:56'; */
var lastOrderExportedAt = new Date(lastExportedOrderData.exported_at); 
Run Code Online (Sandbox Code Playgroud)

currentDateTime结果: 2016-05-25 12:30:02 - > Wed Wed 25 2016 12:30:02 GMT-0400 (EDT)

lastOrderExportedAt结果: 2016-01-12 16:53:56> 2016年1月12日星期二16:53:56 GMT-0500 (EST)

只要日期在同一时区,我就不关心时区.

更新

我的日期现在正在使用ISO-8601标准格式输入,但我的问题仍然存在.2016-05-25T14:04:00-05:00结果为GMT-0400,2016-01-12T16:53:56-05:00结果为GMT -0500

T.J*_*der 7

他们在同一时区(美国东部).区别在于五月份是夏令时期间,因此是东部夏令时间(EDT),一月一次不是,因此是东部标准时间.

重要的是要注意它们的基础时间值(例如,来自dt.getTime())不受时区的影响,并且由于两个日期都已被解析(在您的示例中)为本地时间,因此可以可靠地比较它们.如果将一个解析为本地时间而另一个解析为UTC,则只会遇到比较它们的问题.


旁注:您依赖于new Date解析这些字符串,这意味着您依赖于从JavaScript引擎到JavaScript引擎可能不同的未指定行为.该唯一字符串格式引擎需要支持的ISO-8601的简化版本,其中这些字符串不在,尤其是完全可能的,一个浏览器的JavaScript引擎将决定解析它们,好像它们是在UTC与另一台发动机的浏览器将决定(正如你的似乎已经完成)将它们解析为本地时间.

您还没有说过要解释字符串的时区,但是如果(例如)它们是UTC,您可以通过替换日期和日期之间的空间,相当容易地将它们更改为ISO-8601格式.时间用a T,并添加Z到最后:

str = str.replace(" ", "T") + "Z";
Run Code Online (Sandbox Code Playgroud)

例如"2016-05-25T12:30:02Z",结果字符串new Date对任何现代JavaScript引擎都有效(因此,不是IE8).

或者,如果你知道它们应该被解释为什么时区偏移(例如,GMT-05:00),你可以用空格替换空格T并在末尾添加时区偏移量:

str = str.replace(" ", "T") + "-05:00";
Run Code Online (Sandbox Code Playgroud)

该字符串(例如"2016-05-25T12:30:02-05:00")也有效new Date.

或者,获取它们的部分:

var parts = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/.exec(str);
Run Code Online (Sandbox Code Playgroud)

...并自己建立日期/时间

// As local time
var dt = new Date(
    +parts[1],     // Year
    +parts[2] - 1, // Month (0 = January)
    +parts[3],     // Day
    +parts[4],     // Hour
    +parts[5],     // Minute
    +parts[6]      // Second
);
Run Code Online (Sandbox Code Playgroud)

要么

// As UTC
var dt = new Date(Date.UTC(
    +parts[1],     // Year
    +parts[2] - 1, // Month (0 = January)
    +parts[3],     // Day
    +parts[4],     // Hour
    +parts[5],     // Minute
    +parts[6]      // Second
));
Run Code Online (Sandbox Code Playgroud)

+上面的一元从字符串到数字强制.(但这并不是绝对必要的,new DateDate.UTC为你做.)