So I have a datestring that looks like
2014-08-02T19:00:00
Which should come out to Aug 02 2014 7PM (EST) but when I create a date object it seems to change it to
Sat Aug 02 2014 15:00:00 GMT-0400 (Eastern Daylight Time)
Basically it seems to be assuming that the datestring was in GMT-0000. Is there a way for me to tell it the GMT of the datestring so it doesn't automatically adjust it?
That's because your datestring is in GMT.
If your datestring actually is in EST, it should look like this:
2014-08-02T19:00:00-04:00
Specification: http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
Do not use the Date constructor to parse strings (it uses Date.parse).
An ISO 8601 format string with not timezone will be parsed as UTC by some browsers (e.g. Firefox per ES5) and local by others (e.g. Chrome per the ES 6 draft) and fail completely in yet others to return NaN (e.g. IE 8). Parse the string yourself so that it is always one or the other.
The following will parse it as UTC:
function parseISOUTC(s) {
var b = s.split(/\D+/);
return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5]));
}
console.log(parseISOUTC('2014-08-02T19:00:00').toISOString()); // 2014-08-02T19:00:00.000Z
Given the change in specification between ES5 and the edition 6 draft, event parsing the one format specified by ECMA-262 in the very latest browsers will remain problematic for some time.
Related
This is what I get in chrome console. I pass "2016-09-05"(YYYY-MM-DD) as the date and it shows me Sept 4,2016 as the date.
Another constructor shows the right date
Passing it comma separated needs some tokenizing + parsing + making month zero indexed which I want to avoid
If you omit the time in the new Date(string) constructor, UTC time is assumed. So the displayed value is actually correct. Use new Date('2016-09-05T00:00') to create the date object in local time.
Edit: while some browsers seem to support the yyyy-MM-dd HH:mm format, it's not officially supported, and, as mentioned in the comments, this doesn't work in Safari. I've updated the answer to use a T instead of a space between date and time.
Per the ECMAScript® 2023 Language Specification:
Date-only forms:
YYYY
YYYY-MM
YYYY-MM-DD
It also includes “date-time” forms that consist of one of the above
date-only forms immediately followed by one of the following time
forms with an optional UTC offset representation appended:
THH:mm
THH:mm:ss
THH:mm:ss.sss
You could use the Solution from UTC Date Conversion.
Which basicall does the following:
console.log(new Date("2014-12-23"));
console.log(convertDateToUTC(new Date("2014-12-23")));
function convertDateToUTC(date) {
return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}
The output would be like that in the console (for me at least :D)
Tue Dec 23 2014 01:00:00 GMT+0100 (Mitteleuropäische Zeit)
Tue Dec 23 2014 00:00:00 GMT+0100 (Mitteleuropäische Zeit)
use setFullYear the syntax is Date.setFullYear(year,month,day)
mydate = new Date();
mydate.setFullYear(2016, 08, 05);
This is what I get in chrome console. I pass "2016-09-05"(YYYY-MM-DD) as the date and it shows me Sept 4,2016 as the date.
Another constructor shows the right date
Passing it comma separated needs some tokenizing + parsing + making month zero indexed which I want to avoid
If you omit the time in the new Date(string) constructor, UTC time is assumed. So the displayed value is actually correct. Use new Date('2016-09-05T00:00') to create the date object in local time.
Edit: while some browsers seem to support the yyyy-MM-dd HH:mm format, it's not officially supported, and, as mentioned in the comments, this doesn't work in Safari. I've updated the answer to use a T instead of a space between date and time.
Per the ECMAScript® 2023 Language Specification:
Date-only forms:
YYYY
YYYY-MM
YYYY-MM-DD
It also includes “date-time” forms that consist of one of the above
date-only forms immediately followed by one of the following time
forms with an optional UTC offset representation appended:
THH:mm
THH:mm:ss
THH:mm:ss.sss
You could use the Solution from UTC Date Conversion.
Which basicall does the following:
console.log(new Date("2014-12-23"));
console.log(convertDateToUTC(new Date("2014-12-23")));
function convertDateToUTC(date) {
return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}
The output would be like that in the console (for me at least :D)
Tue Dec 23 2014 01:00:00 GMT+0100 (Mitteleuropäische Zeit)
Tue Dec 23 2014 00:00:00 GMT+0100 (Mitteleuropäische Zeit)
use setFullYear the syntax is Date.setFullYear(year,month,day)
mydate = new Date();
mydate.setFullYear(2016, 08, 05);
There is a funny thing in JavaScript, not a big deal but I would like to know, why is this happening.
If you do this:
new Date('2014-6-12')
you'll get:
Thu Jun 12 2014 00:00:00 GMT-0600 (Central America Standard Time)
which is totally fine but if you do the same using the day with the format 'dd' instead of 'd' like this:
new Date('2014-06-12')
you'll get a different result:
Wed Jun 11 2014 18:00:00 GMT-0600 (Central America Standard Time)
Because '2014-06-12' appears to be an ISO 8601 date format without a time zone, so it's treated as UTC (per ES5) by most browsers but not all. '2014-6-12' is seen as some other format so is treated as local.
ES6 will change that so that ISO 8601 dates without a timezone should be treated as local (per ISO 8601). Confused?
ECMAScript 2015 was originally interpreted as treating ISO 8601 date only forms as local, but that was changed to treat them as UTC. All subsequent versions of ECMAScript also treat them as UTC (which is inconsistent with ISO 8601).
So do not parse strings with the built-in parser (i.e. new Date(string) or Date.parse(string)), its behaviour is inconsistent across browsers and not necessarily standards compliant. Use a library, or write your own simple parser:
// Expect year-month-day, treat as local date
function parseYMD(s) {
var b = s.split(/\D+/);
return new Date(b[0], --b[1], b[2]);
}
The above is simple but does not test if the date is valid, to do that takes an extra line:
// Expect year-month-day, treat as local date
function parseYMD(s) {
var b = s.split(/\D+/);
var d = new Date(b[0], --b[1], b[2]);
return d && d.getFullYear() == b[0] && d.getDate() == b[2]? d : NaN;
}
Also see Why does Date.parse give incorrect results?
var stdate=document.forms["myForm"]["from"].value;
var endate=document.forms["myForm"]["to"].value;
var fromDate = new Date(stdate);
var toDate = new Date(endate);
alert(fromDate);
Input:
from: 19-Mar-2014 03:13:50 PM
Output: (in IE & Firefox)
invalid Date
in Chrome broswer:
Wed Mar 19 2014 15:13:50 GMT-0400 (Eastern Daylight Time)
What date format should I use so that all browsers support? Or how should I handle it?
In most cases, new Date(datestring) is all you need. But you need to chose the format carefully.
Here's a nice compatibility table: http://dygraphs.com/date-formats.html
The short version is this:
Dates only? use YYYY/mm/DD; never use hyphens in this format
Need time, but local time is OK? use YYYY/mm/DD HH:MM:SS; again, no hyphens
OK to ignore IE<9? Consider using ISO8601 with whole seconds (YYYY-mm-DDTHH:MM:SSZ, or with time-zone)
Need a UTC time in IE8? You'll have to do something clever. Xotic's answer looks good here.
As documented on MSDN (IE) - the Date constructor supports either a timestamp or a Datestring in a Format supported by Date.parse. According to the docs this is either RFC2822 or ISO 8601. some examples: 2011-10-10 or Mon, 25 Dec 1995 13:30:00 GMT should be valid arguments.
I would use an ISO8601
formatted string in UTC as my input, but then manually
split
this string into parts and feed them into my
Date
constructor thus avoiding date parsing issues.
Example
var iso8601 = '2014-03-19T03:13:50.000Z',
parts = iso8601.slice(0, -1).split(/[\-T:]/),
dateObject;
parts[1] -= 1;
dateObject = new Date(Date.UTC.apply(undefined, parts));
console.log(dateObject.toUTCString());
Output
Wed, 19 Mar 2014 03:13:50 GMT
On jsFiddle
I am creating new date objects in javascript and seeing some inconsistencies depending on whether I use the dateString parameter vs the year/month/day integer parameters.
Here's an example:
var dt1 = new Date(1979,3,5);
var dt2 = new Date('1979-04-05');
jsFiddle with example
dt1 is assigned the value: Thu Apr 05 1979 00:00:00 GMT-0500 (Central Daylight Time)
dt2 is assigned the value: Wed Apr 04 1979 19:00:00 GMT-0500 (Central Daylight Time)
Can someone explain this behavior? The second example (dt2) happens to be the format that Chrome is returning a selected date from input[type=date] elements which is why I'm trying to figure this out.
It looks like the form '1979-04-05' is interpreted as a UTC date (and then that UTC date is converted to local time when displayed). The form new Date(1979,3,5); is interpreted as local time. You can use Date.UTC to force UTC time for the 3-argument form (see docs).
Date parsing (and timezone handling in particular) is generally not uniform across browsers, and it's better not to depend on it - use UTC whenever possible, or use a separate library like Date.js or moment.js.