我有一个问题,JavaScript日期对象构建不正确。 我不知道如何最好地解决这个问题。 这就是我正在做的事情:
var date = new Date('2016-11-31');现在。 我知道11月份没有31天。 这是一个意外的事故。 问题不是这个日期简单地没有构建,它实际上是建立在12月1日?
现在我想这可能是一个语言环境问题,因为在JSFiddle(或下面的StackOverflow片段)中尝试相同时,我会得到10月31日?
var date = new Date('2016-11-31'); console.log(date);有谁知道我如何解决这个问题?
I have an issue whereby a JavaScript Date object is being built incorrectly. I'm not sure how best to resolve this issue. This is what I'm doing:
var date = new Date('2016-11-31');Now. I understand that November does not have 31 days. This is an intended accident. The problem is rather than this date simply failing to construct, it actually builds as December 1st??
Now I think this maybe a locale issue, as when attempting the same in JSFiddle (or StackOverflow snippets as below), I get October 31st?
var date = new Date('2016-11-31'); console.log(date);Does anyone know how I can get around this issue?
最满意答案
问题不是这个日期简单地没有构建,它实际上是建立在12月1日?
现在我想这可能是一个区域问题...
不,这是一个设计功能。 Date明确地设计为处理日期之间的滚动(在这种情况下,我认为它可能是抽象的DateFromTime操作 ),这就是为什么像myDate.setDate(myDate.getDate() + 1)这样的东西可以可靠地用于递增一天,即使从一个月到下一个月。
在评论中,您问过如果日期字符串在您的问题中识别的方式无效,是否会失败; 我知道的唯一方法是在之后检查结果:
// Note: This example only handles YYYY-MM-DD, not times function strictCreateDate(str) { var date = new Date(str); if (isNaN(date.getTime())) { throw new Error("Invalid date: '" + str + "'"); } var parts = str.split("-"); if (+parts[0] != date.getFullYear() || +parts[1] != date.getMonth() + 1 || +parts[2] != date.getDate()) { throw new Error("Invalid date: '" + str + "'"); } return date; }(如果您希望返回无效的Date实例而不是抛出错误,请将上面的第一个throw更改为return date;第二个return new Date(NaN); )
例:
// Note: This example only handles YYYY-MM-DD, not times function strictCreateDate(str) { var date = new Date(str); if (isNaN(date.getTime())) { throw new Error("Invalid date: '" + str + "'"); } var parts = str.split("-"); if (+parts[0] != date.getFullYear() || +parts[1] != date.getMonth() + 1 || +parts[2] != date.getDate()) { throw new Error("Invalid date: '" + str + "'"); } return date; } function test(str) { try { var dt = strictCreateDate(str); console.log(str + " => " + dt.toISOString()); } catch (e) { console.log(str + " => " + e.message); } } test('2016-11-30'); test('2016-11-31'); test('2016-08-01');注意 :ES5规范中存在错误,该错误定义了new Date("2016-08-01")将字符串解释为UTC的行为,违反了ISO-8601标准,称其应解释为“当地时间” “因为没有时区指示符。 这个规范错误在ES2015中得到了修复,但不幸的是,一段时间以来,浏览器仍然在持续使用ES5版本(特别是Firefox)。 我刚刚测试了最近的Chrome和Firefox,他们现在都遵循ES2015标准,但重要的是要小心。 如果您的代码可能在实现错误行为的浏览器上运行,请将标准+/-HH:MM格式的时区指示符添加到字符串的末尾(或向其添加"Z"并使用UTC函数[ getUTCFullYear等]而不是上面的本地时间函数[ getFullYear等])。
The problem is rather than this date simply failing to construct, it actually builds as December 1st??
Now I think this maybe a locale issue...
No, it's a design feature. Date is expressly designed to handle rollover between dates (in this case, I think it's probably down to the abstract DateFromTime operation), which is why things like myDate.setDate(myDate.getDate() + 1) can reliably be used to increment the day, even when going from one month to the next.
In a comment you've asked if there's a way that will fail if the date string is invalid in the way you identify in your question; the only way I know is to check the result afterward:
// Note: This example only handles YYYY-MM-DD, not times function strictCreateDate(str) { var date = new Date(str); if (isNaN(date.getTime())) { throw new Error("Invalid date: '" + str + "'"); } var parts = str.split("-"); if (+parts[0] != date.getFullYear() || +parts[1] != date.getMonth() + 1 || +parts[2] != date.getDate()) { throw new Error("Invalid date: '" + str + "'"); } return date; }(If you prefer to return an invalid Date instance rather than throwing an error, change the first throw above to return date; and the second one to return new Date(NaN);.)
Example:
// Note: This example only handles YYYY-MM-DD, not times function strictCreateDate(str) { var date = new Date(str); if (isNaN(date.getTime())) { throw new Error("Invalid date: '" + str + "'"); } var parts = str.split("-"); if (+parts[0] != date.getFullYear() || +parts[1] != date.getMonth() + 1 || +parts[2] != date.getDate()) { throw new Error("Invalid date: '" + str + "'"); } return date; } function test(str) { try { var dt = strictCreateDate(str); console.log(str + " => " + dt.toISOString()); } catch (e) { console.log(str + " => " + e.message); } } test('2016-11-30'); test('2016-11-31'); test('2016-08-01');Note: There was an error in the ES5 specification which defined the behavior of new Date("2016-08-01") to interpret the string as UTC, in contravention of the ISO-8601 standard saying it should be interpreted as "local time" because there is no time zone indicator. This specification error was fixed in ES2015, but unfortunately for some time there were browsers in the wild (Firefox in particular) that continued the ES5 version. I just tested both recent Chrome and Firefox, and they both now follow the ES2015 standard, but it's important to beware. If there's any chance your code may run on browsers implementing incorrect behavior, add a timezone indicator in the standard +/-HH:MM format to the end of your string (or add a "Z" to it and use the UTC functions [getUTCFullYear, etc.] instead of the local time functions [getFullYear, etc.] above).
更多推荐
发布评论