Reputation: 533
Date formatting issues with Javscript Date().
Background: I'm modifying Jquery UI datepicker and am having trouble with months and dates returning incorrect values.
$('#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
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?
Why does 'd4' return 20160731 when the date set is 1st August?
Why does d3 work correctly?
My Assumption is that that the ISO date somehow subtracts the GMT+10 and gets the previous day.
I'm Aware of this step (protoype a function) to try and format Get String in YYYYMMDD format from JS date object? 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('');
Upvotes: 0
Views: 3564
Reputation: 147363
Why does 'd2' return 20160730 when the object returns 31st July?
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. 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.
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:
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:
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, i.e. the UTC date is the same as your local date. 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.
In all of the above, the actual time value of the Date object is 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.
* Note that this is contrary to ISO 8601, which specifies that dates without a time component should be treated as local. But ECMA-262 treats them as 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. 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.
Upvotes: 2