Javascript中的错误日期 [英] Wrong Date in Javascript
问题描述
我正在尝试在我的Web应用程序中使用fullcalendar.io jquery插件。为此,我将一组事件数据解析为fullcallendar的格式,如下所示:
Date.prototype.addHours = function(h) {
this.setHours(this.getHours()+ h);
返回这个;
}
Date.prototype.addMins = function(h){
this.setMinutes(this.getMinutes()+ h);
返回这个;
}
data.forEach(function(entry){
events [i] = {
title:'Clase',
start:new Date(entry.date),
end:new Date(entry.date).addHours(entry.hours).addMins(entry.mins)
}
i ++;
});
现在我的数据是这样形成的:
[{date:2015-05-01T15:00:00.000,hours:4,mins:30},{date 05-04T15:00:00.000,小时:4,分钟:30},...]
然而,当我创建一个Date对象15:00的时候,我会得到17:00的时间。我相信这与时区有关(我目前在夏季时间是GMT + 2),但我不知道如何解决它。
不幸的是,当ES5添加了日期/时间格式到JavaScript,他们犯了一个错误:他们说没有时区的字符串应该被视为GMT,而不是当地时间;但是在ISO-8601中,它们是基于格式的,没有时区的字符串是本地时间。
ES6更改它匹配ISO-8601,所以现在我们有一个问题:有些引擎使用ES5规则(例如当前的Firefox),某些引擎使用ES6规则(例如当前的Chrome)。
所以你需要在这些规则上指定一个时区字符串可靠地解析,跨浏览器:
-
如果它们是GMT,那很容易:只需添加一个Z给他们:
var dt = new Date(entry.date +Z);
-
如果它们是当地时间,那很难,因为你必须允许对于DST,所以使用的偏移量随日期而变化。
var dt = new Date(entry.date +Z );
dt.setMinutes(dt.getMinutes()+ dt.getTimezoneOffset());
我 认为 DST边界,但您需要测试。
您可以自己处理,也可以使用库为你处理它。有几个选择,只需搜索JavaScript日期库。一个非常受欢迎的一个(不是双关语)是 http://momentjs.com 。
#1的示例,只需添加 Z
,使GMT / UTC可靠的时间:
Date.prototype.addHours = function(h){this.setHours(this.getHours()+ h); return this;}; Date.prototype.addMins = function(h){this.setMinutes(this.getMinutes()+ h); return this;}; var data = [{date:2015-05-01T15:00:00.000,hours:4,mins:30},{date:2015-05-04T15 :00:00.000,hours:4,mins:30}]; data.forEach(function(entry){snippet.log(entry.date +=>+ new Date(entry.date + Z));});
- 脚本提供`snippet`对象,参见http://meta.stackexchange.com/a/242144/134069 - >< script src =http://tjcrowder.github.io/simple-snippets- console / snippet.js>< / script>
#2的例子,假设字符串是本地时间:
Date.prototype.addHours = function(h){this .setHours(this.getHours()+ h); return this;}; Date.prototype.addMins = function(h){this.setMinutes(this.getMinutes()+ h); return this;}; var data = [{date:2015-05-01T15:00:00.000,hours:4,mins:30},{date:2015-05-04T15 :00:00.000,hours:4,mins:30}]; data.forEach(function(entry){var dt = new Date(entry.date +Z); dt.setMinutes getMinutes()+ dt.getTimezoneOffset()); snippet.log(entry.date +=>+ dt);});
<! - 脚本提供`snippet`对象,请参见http://meta.stackexchange.com/a/242144/134069 - >< script src =http://tjcrowder.github.io/simple-snippets-console/snippet.js>< / script>
/ div>
I am trying to use the fullcalendar.io jquery plugin in my web application. For that, I parse a set of event data into fullcallendar's format like this:
Date.prototype.addHours = function(h) {
this.setHours(this.getHours() + h);
return this;
}
Date.prototype.addMins = function(h) {
this.setMinutes(this.getMinutes() + h);
return this;
}
data.forEach(function(entry) {
events[i] = {
title : 'Clase',
start : new Date(entry.date),
end : new Date(entry.date).addHours(entry.hours).addMins(entry.mins)
}
i++;
});
Now my data is formated like this:
[{"date":"2015-05-01T15:00:00.000","hours":4,"mins":30},{"date":"2015-05-04T15:00:00.000","hours":4,"mins":30}, ... ]
However when I create a Date object for 15:00 hours, I get a 17:00 time. I am sure this is related to timezone (I am currently in GMT+2 due to summer time), but I'm not sure how to fix it.
Sadly, when ES5 added the date/time format to JavaScript, they made a mistake: They said that strings without a timezone should be treated as though they were GMT, not local time; but in ISO-8601, which is what they based the format on, strings without timezones are local time.
ES6 changes it to match ISO-8601, so now we have a problem: Some engines use the ES5 rule (current Firefox, for instance), and some engines use the ES6 rule (current Chrome, for instance).
So you need to specify a timezone on those strings to parse them reliably, cross-browser:
If they're meant to be GMT, it's easy: Just add a Z to them:
var dt = new Date(entry.date + "Z");
If they're meant to be local time, it's harder, because you have to allow for DST, so the offset to use varies by the date.
var dt = new Date(entry.date + "Z"); dt.setMinutes(dt.getMinutes() + dt.getTimezoneOffset());
I think that still works correctly on DST boundaries, but you'll want to test.
You can handle this yourself, or you can use a library to handle it for you. There are several choices, just search for "JavaScript date library". One quite popular one at the moment (no pun) is http://momentjs.com.
Example of #1, just adding Z
to make those times GMT/UTC reliably:
Date.prototype.addHours = function(h) {
this.setHours(this.getHours() + h);
return this;
};
Date.prototype.addMins = function(h) {
this.setMinutes(this.getMinutes() + h);
return this;
};
var data = [{
"date": "2015-05-01T15:00:00.000",
"hours": 4,
"mins": 30
}, {
"date": "2015-05-04T15:00:00.000",
"hours": 4,
"mins": 30
}];
data.forEach(function(entry) {
snippet.log(entry.date + " => " + new Date(entry.date + "Z"));
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Example of #2, assuming the strings are local time:
Date.prototype.addHours = function(h) {
this.setHours(this.getHours() + h);
return this;
};
Date.prototype.addMins = function(h) {
this.setMinutes(this.getMinutes() + h);
return this;
};
var data = [{
"date": "2015-05-01T15:00:00.000",
"hours": 4,
"mins": 30
}, {
"date": "2015-05-04T15:00:00.000",
"hours": 4,
"mins": 30
}];
data.forEach(function(entry) {
var dt = new Date(entry.date + "Z");
dt.setMinutes(dt.getMinutes() + dt.getTimezoneOffset());
snippet.log(entry.date + " => " + dt);
});
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
这篇关于Javascript中的错误日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!