Javascript 返回的日期问题比设置日期少 1 天 - 时区

Javascript Date issues returning 1 day less than set date - timezone

Javscript Date() 的日期格式问题。

背景:我正在修改 Jquery UI 日期选择器,但在处理月份和日期 return 错误值时遇到问题。

$('#datefield').datepicker({
   beforeShowDay: function(date) {
      // issues experienced here - isolation test code below
      // Mon Aug 01 2016 00:00:00 GMT+1000 (AUS Eastern Standard Time)
      // DateMonth: 8 - ISO: 20160731
   }
})

基于 http://www.w3schools.com/jsref/jsref_obj_date.asp

的 JS Date() 构造

示例代码:

var d1 = new Date();
var d1Month = d1.getMonth()+1;
var d1ISO = d1.toISOString().slice(0,10).replace(/-/g,"");

console.log(d1);
console.log('1Month: '+d1Month+' ISO: '+d1ISO);

var d2 = new Date(2016,06,31);
var d2Month = d2.getMonth()+1;
var d2ISO = d2.toISOString().slice(0,10).replace(/-/g,"");

console.log(d2);
console.log('2Month: '+d2Month+' ISO: '+d2ISO);

var d3 = new Date('2016-07-31');
var d3Month = d3.getMonth()+1;
var d3ISO = d3.toISOString().slice(0,10).replace(/-/g,"");

console.log(d3);
console.log('3Month: '+d3Month+' ISO: '+d3ISO);

var d4 = new Date(2016, 07, 01);
var d4Month = d4.getMonth()+1;
var d4ISO = d4.toISOString().slice(0,10).replace(/-/g,"");

console.log(d4);
console.log('4Month: '+d4Month+' ISO: '+d4ISO);

输出(控制台):

Wed Aug 24 2016 11:30:51 GMT+1000 (AUS Eastern Standard Time)
1Month: 8 ISO: 20160824

*Sun Jul 31 2016 00:00:00 GMT+1000 (AUS Eastern Standard Time)
2Month: 7 ISO: 20160730

Sun Jul 31 2016 10:00:00 GMT+1000 (AUS Eastern Standard Time)
3Month: 7 ISO: 20160731

*Mon Aug 01 2016 00:00:00 GMT+1000 (AUS Eastern Standard Time)
4Month: 8 ISO: 20160731

为什么对象 return 是 7 月 31 日时 'd2' return 20160730?

为什么日期设置为8月1日时'd4'return20160731?

为什么 d3 可以正常工作?

我的假设是 ISO 日期以某种方式减去 GMT+10 并得到前一天。

我知道这个步骤(原型函数)来尝试格式化 Get String in YYYYMMDD format from JS date object? 但对我来说为什么上面会产生不同的结果仍然是个谜...

return [this.getFullYear(), !mm[1] && '0', mm, !dd[1] && '0', dd].join('');

Why does 'd2' return 20160730 when the object returns 31st July?

因为当你这样做时:

var d2 = new Date(2016,06,31);

您创建了一个相当于主机系统当前时区 00:00:00 2016 年 7 月 31 日的日期。当你这样做时:

console.log(d2);

您当前的系统设置用于在您的主机系统的时区(显然是 GMT+10:00)生成一个字符串,并将显示相当于 2016-07-31T00:00:00+10:00.

但是当你这样做时:

console.log('2Month: '+d2Month+' ISO: '+d2ISO);

日期位于格林威治标准时间时区,或者早 10 小时,因此如果时间早于 10:00,则日期将为前一天 (GMT),您将看到:

2016-07-30T14:00:00Z

但是因为您将时间部分从字符串中切掉,所以您只能看到日期部分。

它 "works" 用于 d3,因为当您这样做时:

var d3 = new Date('2016-07-31');

日期字符串被视为 UTC*,因此您正在为 2016-07-31T00:00:00Z 创建一个日期,相当于 2016-07-31T10:00:00+ 10:00,即 UTC 日期与您当地的日期相同。注意输出:

console.log(d3);

是在10:00:00(因为内置的toString考虑了你的系统时区,所以在显示的日期上增加了10小时),这是你的时区偏移量。

在上述所有情况下,Date 对象的实际时间值都是 UTC。主机系统时区偏移量用于最初创建时间值,用于年、月、日、小时的 getset 方法,等等(因为夏令时改变了时区)以及生成人类可读的日期字符串时。

* 请注意,这与 ISO 8601 相悖,ISO 8601 规定没有时间成分的日期应被视为本地日期。但 ECMA-262 将它们视为 UTC。在某些版本的浏览器中,“2016-07-31”将被视为无效,其他浏览器将被视为本地,而最新版本将其视为 UTC。这就是为什么 强烈 建议总是手动解析日期字符串(使用你自己的函数或带有解析器的库),这样你就可以控制它的解析方式和时区的应用方式。