我正在创建这样的日期:
var StartDate = new Date(data.feed.entry[i].gd$when[j].startTime);
收到日期字符串时,在表格中指定日期和时间:
"2014-04-12T20:00:00.000-05:00"
Date()
解释这个完美的回归:
Sat Apr 12 2014 19:00:00 GMT-0500 (CDT)
但是,当收到日期字符串时,表格中没有时间信息:
"2014-04-07"
然后Date()
将其解释为:
Sat Apr 05 2014 19:00:00 GMT-0500 (CDT)
看起来Date()
正在把-07作为时间,我不知道它在哪里得到的日期是05.任何想法可能是什么问题?
可能是,不知何故,Date()
正在解释不同的时区,因为在第一个字符串中,时区是在最后确定的,但在“全天”事件中没有时区的指示。
有人发现了这个问题吗?如果是的话,你是怎么解决的?
更新:在研究了一点这个解析问题后,我发现了一些非常奇怪的东西:
以下声明:
new Date("2014-4-07")
将返回2014年4月7日星期一00:00:00 GMT-0500(CDT),这是正确的,但是以下一个:
new Date("2014-04-07")
返回2014年4月6日星期日19:00:00 GMT-0500(CDT),这是错误的。所以,无论出于何种原因,似乎填充零都会影响解析日期的方式!
答案 0 :(得分:1)
您使用Date()
功能错误。
它只接受以下格式的参数。
//No parameters
var today = new Date();
//Date and time, no time-zone
var birthday = new Date("December 17, 1995 03:24:00");
//Date and time, no time-zone
var birthday = new Date("1995-12-17T03:24:00");
//Only date as integer values
var birthday = new Date(1995,11,17);
//Date and time as integer values, no time-zone
var birthday = new Date(1995,11,17,3,24,0);
来源:MDN。
Date()
函数不接受时区作为参数。您认为时区参数有效的原因是因为它显示的是您输入的相同时区,但这是因为您处于同一时区。
您将Sat Apr 05 2014 19:00:00 GMT-0500 (CDT)
作为日期输出(" 2014-04-07")的原因仅仅是因为您以不同的方式使用它。
new Date(parameters)
会根据传递的参数给出输出。
Date(parameters)
会将输出作为当前日期和时间,无论您传递哪个参数。
答案 1 :(得分:1)
在ES5之前,解析日期字符串完全取决于实现。 ES5指定了可能的浏览器支持的a version of ISO 8601,但不是全部。指定的格式仅支持Z时区(UTC),如果缺少时区,则采用UTC。缺少时区的支持是不一致的,有些实现会将字符串视为UTC,有些则视为本地。
要确定,您应该自己解析字符串,例如
/* Parse an ISO string with or without an offset
** e.g. '2014-04-02T20:00:00-0600'
** '2014-04-02T20:00:00Z'
**
** Allows decimal seconds if supplied
** e.g. '2014-04-02T20:00:00.123-0600'
**
** If no offset is supplied (or it's Z), treat as UTC (per ECMA-262)
**
** If date only, e.g. '2014-04-02', treat as UTC date (per ECMA-262)
*/
function parseISOString(s) {
var t = s.split(/\D+/g);
var hasOffset = /\d{2}[-+]\d{4}$/.test(s);
// Whether decimal seconds are present changes the offset field and ms value
var hasDecimalSeconds = /T\d{2}:\d{2}:\d{2}\.\d+/i.test(s);
var offset = hasDecimalSeconds? t[7] : t[6];
var ms = hasDecimalSeconds? t[6] : 0;
var offMin, offSign, min;
// If there's an offset, apply it to minutes to get a UTC time value
if (hasOffset) {
offMin = 60 * offset / 100 + offset % 100;
offSign = /-\d{4}$/.test(s)? -1 : 1;
}
min = hasOffset? +t[4] - offMin * offSign : (t[4] || 0);
// Return a date object based on UTC values
return new Date(Date.UTC(t[0], --t[1], t[2], t[3]||0, min, t[5]||0, ms));
}
ISO 8601日期字符串应视为UTC(根据ECMA-262),因此如果您是UTC-0500,则:
new Date('2014-04-07'); // 2014-04-06T19:00:00-0500
OP中描述的行为表明主机不符合ECMA-262。进一步鼓励自己解析字符串。如果您希望将日期视为本地日期,则:
// Expect string in ISO 8601 format
// Offset is ignored, Date is created as local time
function parseLocalISODate(s) {
s = s.split(/\D+/g);
return new Date(s[0], --s[1], s[2],0,0,0,0);
}
在您的功能中,您可以执行以下操作:
var ds = data.feed.entry[i].gd$when[j].startTime;
var startDate = ds.length == 10? parseLocalISODate(ds) : parseISOString(ds);
另请注意,按照惯例,以大写字母开头的变量是为构造函数保留的,因此 startDate ,而不是 StartDate 。
答案 2 :(得分:0)
(我会添加评论,但我还没有50个代表)
查看内容
new Date()。getTimezoneOffset()
返回,我会期待一个很大的负值,这将是你问题的唯一合理解释。
我在过去的日期转换方面遇到了一些问题,特别是白天节省时区,并且为了解决这个问题,我总是将时间明确地设置为正午(上午12:00)。因为我认为你正在使用淘汰赛,你可以制作一个计算的观察者,它附加一个" T20:00:00.000-05:00"或适当的时区到所有"仅限#34;日期