Join the DZone community and get the full member experience.Join For Free
Date function itself was no exception. It is based on code that was ultimately deprecated in Java.
let date = new Date(2011, 1, 22); // Notice the date produced has a time attached: // Tue Feb 22 2011 00:00:00 GMT+0000 (Greenwich Mean Time)
As we did above, parsing dates work fine if you know months start at 0, but parsing date strings vary significantly across browsers. It is strongly advised not to parse date strings. Before the ECMAScript 5 specification, how
Date parsed string dates was never defined, and different browsers have many historical quirks that make it very unreliable.
let parseMyDate = Date.parse('2022-03-21T11:00:01+00:00');
However, that is not the case. Many browsers allow date parsing outside of this format. This is where it has the potential to get confusing. You want to parse a date format in standard
dd/mm/yyyy date format. You take an expected date and pass it into the
let myDate = new Date("5/1/2020"); console.log(myDate);
This uses the US date format in all modern browsers, i.e.,
mm/dd/yyyy - meaning it returns May 1st, not Jan 5th, leading to unexpected results.
Suppose you have a date that has no time or time zone associated with it:
let myDate = Date.parse('01 Jan 1999'); console.log(myDate);
You might think there is nothing immediately confusing about this - it represents a fixed date in time. However:
- If your time zone is UTC, this will return
- If your time zone is UTC+3:00, this will return
915138000000, i.e., 3 hours more.
- If your time zone is UTC-5:00, this will return
let date = new Date(2011, 2, 22);
Only, that gives us
let date = new Date(2011, 1, 22);
Incorrect Dates Skip Ahead
You have accidentally created an incorrect date, say 31st Feb 2022. You pass this into your date function, by mistake, from a database or API:
let date = new Date(2011, 1, 31); console.log(date)
You might think that this will return an
Invalid Date or
Date to return errors on all incorrect dates.
let myDate = new Date("0"); console.log(myDate);
You might think that this will return the year 0, or perhaps the Unix epoch, but it returns the year 2000 -
Sat Jan 01, 2000, 00:00:00 GMT+0000 (Greenwich Mean Time).
Even more strangely, though, if we try to increase this, it starts counting in months:
console.log(new Date("5")); // Tue May 01 2001 00:00:00 GMT+0100 (British Summer Time) console.log(new Date("11")); // Thu Nov 01 2001 00:00:00 GMT+0000 (Greenwich Mean Time) console.log(new Date("4")); // Sun Apr 01 2001 00:00:00 GMT+0100 (British Summer Time)
If you try to do a
new Date("13"), we'll get an
Invalid Date since there is no 13th month.
If we only pass one number to the
new Date(), it will treat it as the Unix timestamp - however, it is not adjusted for time zone. For example, in UTC, the following code returns
Thu Jan 01 1970 00:00:00 GMT+0000 (Greenwich Mean Time):
That makes sense since it's the Unix epoch - however, if we are in UTC-5:00, that code returns
Wed Dec 31 1969 19:00:00 GMT-0500 (Eastern Standard Time) - i.e., 5 hours before. By default, time zones can lead to a lot of confusion - if we expected the date to be 1st Jan 1970, we immediately have an issue when using a method like
Date().toLocaleString(). Ultimately, we can resolve this using the technique
.toUTCString() - but this complication leads to confusion.
You might have thought we've gotten off easy, and only timestamps and time zones are broken - but even years are inconsistent. If we wanted to create a date for the 1st Jan, in the year 0, you might think we'd write this:
console.log(new Date(0, 0, 0));
Since months start from 0, this looks right - but if the year is less than 100, 0 means the year 1900. Alright, you might think, I suppose this should return 1st Jan 1900 instead - but that's wrong too - since days are indexed from 1, not 0. The above code returns
Sun Dec 31 1899 00:00:00 GMT+0000 (Greenwich Mean Time) - since the 0th day of the month is counted as the last day from the previous month. Here are a few other examples
console.log(new Date(0, 0, 0)); // Sun Dec 31 1899 00:00:00 GMT+0000 (Greenwich Mean Time) console.log(new Date(50, 0, 0)); // Sat Dec 31 1949 00:00:00 GMT+0000 (Greenwich Mean Time) console.log(new Date(30, 0, 0)); // Tue Dec 31 1929 00:00:00 GMT+0000 (Greenwich Mean Time) console.log(new Date(24, 0, 0)); // Mon Dec 31 1923 00:00:00 GMT+0000 (Greenwich Mean Time)
As soon as you get above the year 100, it then does go back to counting the years normally. So the below code gives us the year 101, not the year 2001:
console.log(new Date(101, 0, 0)); // Fri Dec 31 0100 00:00:00 GMT-0001 (Greenwich Mean Time)
This may be useful if you use years after 1900, but it is incredibly counterintuitive for anything before.
The main reason is that most of the web has been built on code that considers the flaws with Date. As such, changing now would result in many websites simply breaking.
Published at DZone with permission of Johnny Simpson, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.