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?
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);
let's say I have this date as input :
var _dateA = 2018-11-15T11:13:26.687Z
If I'm doing, whatever,
var _dateB = new Date(_date)
or
var _dateB = moment(_date)
I get this as result ==>
_dateB = Thu Nov 15 2018 12:13:26 GMT+0100 (heure normale d’Europe centrale)
I understood that there's timezone trouble, but how can I get a Date object or Moment object, without having this one hour more?
Wanted result => Thu Nov 15 2018 11:13:26 GMT+0100
Current result => Thu Nov 15 2018 12:13:26 GMT+0100
You need to use Date.toUTCString() that converts date to string, using the UTC time zone
var _dateA = '2018-11-15T11:13:26.687Z';
var _dateB = new Date(_dateA);
console.log(_dateB.toUTCString());
When you "output" a Date object via console.log(), alert(), etc the toString() method is used by default, converting the date object to a local timezone string for display (which is why you are seeing your date in your local time).
Parsing date strings with the Date constructor is not recommended (although, I suspect that most browsers probably handle ISO 8601 dates, like the one in your question, fairly well) - see the dateString parameter note here. So, if you need to construct a date object as well as output a date string, then you could parse the ISO 8601 string with split() using a regex character set for multiple delimiters, then construct a UTC date object with new Date(Date.UTC(...)). You could also do this with moment.js but the below should illustrate what is happening in a bit more detail.
For example:
const text = '2018-11-15T11:13:26.687Z'
const [y, m, d, hh, mm, ss, ms] = text.split(/[-T:.Z]/);
const date = new Date(Date.UTC(y, m - 1, d, hh, mm, ss, ms));
console.log(date.toLocaleString()); // date string in local timezone
console.log(date.toUTCString()); // UTC date string
console.log(JSON.stringify(date)); // ISO 8601 date string in most browsers
I have a UTC string "2018-04-25T13:36:00" which I pass into this function:
function convertUTCDateToLocalDate(dateString) {
var newDate = new Date(dateString);
newDate.setMinutes(dateString.getMinutes() - dateString.getTimezoneOffset());
return newDate;
}
var localDate = convertUTCDateToLocalDate(new Date("2018-04-25T13:36:00"));
console.log(localDate);
Chrome, Firefox and Edge returns correctly as (PASS):
Wed Apr 25 2018 06:36:00 GMT-0700 (PDT)
However, Safari returns it as (FAIL):
Tue Apr 24 2018 23:36:00 GMT-0700 (PDT)
Why is Safari being a stickler?
The string "2018-04-25T13:36:00" should be parsed as local, however Safari gets it wrong and parses it as UTC. Since you want to parse it as UTC, one simple (but not recommended) method is to simply add "Z" to the string so all browsers parse it as UTC:
var s = '2018-04-25T13:36:00';
console.log(new Date(s+'Z').toString());
However, general advice is never use the built-in parser as it is notoriously problematic (see Why does Date.parse give incorrect results?), write your own parser for your particular format or use a library. To parse your format as UTC, consider:
var s = '2018-04-25T13:36:00';
// Parse YYYY-MM-DDTHH:mm:ss as UTC
function parseUTC(s) {
var b = s.split(/\D/);
return new Date(Date.UTC(b[0],--b[1],b[2],b[3],b[4],b[5]))
}
var d = parseUTC(s);
console.log(d.toISOString());
console.log(d.toString());
How can I create a Date object from a date with this format:
03/23/2016 02:00:00 PM
The Date object can parse strings: new Date('03/23/2016 02:00:00 PM')
For example:
var date = new Date('03/23/2016 02:00:00 PM') // => "Wed Mar 23 2016 14:00:00 GMT-0700 (PDT)"
date.getFullYear() // => 2016
However, I would recommend using a library that someone else has already spent time considering the edge cases, like time zones, etc. (a good one I've used is moment.js).
Keep in mind (from the moment.js docs):
Warning: Browser support for parsing strings is inconsistent. Because there is no specification on which formats should be supported, what works in some browsers will not work in other browsers.
For consistent results parsing anything other than ISO 8601 strings, you should use String + Format.
var date = new Date("3/23/2016 02:00:00 PM");
console.log(date);
You can then access all the methods of the Date object.
Looking at MDN
var date = new Date('03/23/2016 02:00:00 PM')
You can use something like date.js:
First use script, then write date:
<script type="text/javascript" src="http://www.datejs.com/build/date.js"></script>
....
document.write(new Date().toString("dd:MM:yyyy hh:mm:ss tt"));
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.