简体   繁体   English

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

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

Date formatting issues with Javscript Date(). Javscript Date()的日期格式问题。

Background: I'm modifying Jquery UI datepicker and am having trouble with months and dates returning incorrect values. 背景:我正在修改Jquery UI datepicker,并且在月份和日期返回错误值时遇到了麻烦。

$('#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
   }
})

Based JS Date() construction on http://www.w3schools.com/jsref/jsref_obj_date.asp 基于http://www.w3schools.com/jsref/jsref_obj_date.asp的 JS Date()构造

Sample code: 样例代码:

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);

Output (console): 输出(控制台):

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

Why does 'd2' return 20160730 when the object returns 31st July? 为什么当对象返回7月31日时,“ d2”返回20160730?

Why does 'd4' return 20160731 when the date set is 1st August? 为什么将日期设置为8月1日,“ d4”返回20160731?

Why does d3 work correctly? 为什么d3可以正常工作?

My Assumption is that that the ISO date somehow subtracts the GMT+10 and gets the previous day. 我的假设是,ISO日期以某种方式减去GMT + 10并得到前一天。

I'm Aware of this step (protoype a function) to try and format Get String in YYYYMMDD format from JS date object? 我知道此步骤(原型函数)尝试从JS日期对象格式化为YYYYMMDD格式的“获取字符串”吗? but its still a mystery to me why the above produces different results... 但是对我来说仍然是一个谜,为什么上述方法会产生不同的结果...

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

Why does 'd2' return 20160730 when the object returns 31st July? 为什么当对象返回7月31日时,“ d2”返回20160730?

Because when you do: 因为当您这样做时:

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

you create a Date equivalent to 31 July, 2016 at 00:00:00 in your host system's current time zone. 您在主机系统的当前时区中创建了一个相当于2016年7月31日00:00:00的日期。 When you do: 当您这样做时:

console.log(d2);

your current system settings are used to generate a string in your host system's time zone (apparently GMT+10:00) and will show the equivalent of 2016-07-31T00:00:00+10:00. 您当前的系统设置用于在主机系统的时区(显然是GMT + 10:00)中生成一个字符串,并显示与2016-07-31T00:00:00 + 10:00等效的字符串。

But when you do: 但是当您这样做时:

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

the date is in time zone GMT, or 10 hours earlier so if the time is before 10:00, then the date will be the previous day (GMT) and you'll see: 日期为格林尼治标准时间(GMT)或早10小时,因此,如果时间在10:00之前,则日期为前一天(GMT),您将看到:

2016-07-30T14:00:00Z

but because you sliced the time part off the string, you only see the date part. 但是因为您将时间部分从字符串中切了下来,所以您只能看到日期部分。

It "works" for d3 because when you do: 它对于d3是“有效的”,因为当您这样做时:

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

the date string is treated as UTC*, so you're creating a date for 2016-07-31T00:00:00Z which is equivalent to 2016-07-31T10:00:00+10:00, ie the UTC date is the same as your local date. 日期字符串被视为UTC *,因此您要为2016-07-31T00:00:00Z创建一个日期,该日期等于2016-07-31T10:00:00 + 10:00,即UTC日期为与您当地的日期相同。 Note that the output of: 请注意输出:

console.log(d3);

is at 10:00:00 (because the built–in toString considers your system time zone, so adds 10 hours to the displayed date), which is your time zone offset. 在10:00:00(因为内置的toString会考虑您的系统时区,因此会在显示的日期上增加10小时),这是您的时区偏移量。

In all of the above, the actual time value of the Date object is UTC. 在上述所有情况下,Date对象的实际时间值为UTC。 The host system time zone offset is used for creating the time value initially, for the get and set methods for year, month, day, hour, etc. (since daylight saving changes the time zone) and when generating human readable date strings. 主机系统时区偏移量最初用于创建时间值,用于年,月,日,小时等的getset方法(因为夏时制会更改时区),并在生成人类可读的日期字符串时使用。

* Note that this is contrary to ISO 8601, which specifies that dates without a time component should be treated as local. *请注意,这违反了ISO 8601,ISO 8601规定了没有时间成分的日期应被视为本地日期。 But ECMA-262 treats them as UTC. 但是ECMA-262将它们视为UTC。 There are certain versions of browsers where '2016-07-31' will be treated as invalid, others where it will be treated as local, while the latest will treat it as UTC. 在某些版本的浏览器中,“ 2016-07-31”将被视为无效,其他版本的浏览器将被视为本地,而最新版本的浏览器将其视为UTC。 That is why it is strongly recommended to always manually parse date strings (use your own function or a library with a parser) so you control how it's parsed and how the time zone is applied. 因此, 强烈建议始终手动分析日期字符串(使用您自己的函数或带有解析器的库),以便您控制如何解析日期字符串以及如何应用时区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM