DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • Segmentation Violation and How Rust Helps Overcome It
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack

Trending

  • Chaos Engineering for Microservices
  • Scaling InfluxDB for High-Volume Reporting With Continuous Queries (CQs)
  • SQL Server Index Optimization Strategies: Best Practices with Ola Hallengren’s Scripts
  • Analyzing “java.lang.OutOfMemoryError: Failed to create a thread” Error
  1. DZone
  2. Coding
  3. Languages
  4. The Many Quirks of JavaScript Dates

The Many Quirks of JavaScript Dates

Let's look at all the JavaScript Dates' oddities, which differ significantly from other languages since most of the web has been built on code that considers the flaws.

By 
Johnny Simpson user avatar
Johnny Simpson
DZone Core CORE ·
Apr. 08, 22 · Analysis
Likes (5)
Comment
Save
Tweet
Share
3.5K Views

Join the DZone community and get the full member experience.

Join For Free

JavaScript dates are weird. Famously, Brendan Eich wrote the first version of JavaScript in 10 days - and the Date function itself was no exception. It is based on code that was ultimately deprecated in Java.

That means JavaScript has inherited a Date function which was found to be buggy and problematic in Java, leaving it full of issues. You may have even encountered some problems yourself. You may be wondering, then, "what's so weird about it?". Let's look at all the quirks and common pitfalls with JavaScript's Date constructor so that you can avoid them.

JavaScript Doesn't Support Dates

The primary JavaScript date constructor is Date, but JavaScript does not support dates. JavaScript only supports date times. All JavaScript dates are Unix timestamps underneath. If we try to create a date, we are creating a date-time. All JavaScript dates default to midnight on that given day with no time specified.

 
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)

Parsing Dates

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.

According to the current specification, only strings conforming to the ISO-8601 standard should be parsable by JavaScript, and any other dates should return NaN, i.e.:

 
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 parse() function:

 
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.

Parsing Dates Defaults to UTC

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 915148800000.
  • 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 915166800000, i.e., 5 hours less. So, if your time zone is west of UTC, for example, -5:00, JavaScript subtracts 5 hours from the Unix timestamp. Since days start at midnight.

If we try to use this timestamp with a different time zone, for example, in a backend system, we won't get 1st Jan 1999; we get 31st Dec 1998! All of this is because JavaScript does not implement dates - every date has a time associated with it - in this case, midnight.

Months Start at 0 in JavaScript Dates

If we want to create a date in JavaScript, we can parse numbers representing the year, month, and day. For example, if we're going to make a date for Feb 22nd, 2011, we'd write this.

 
let date = new Date(2011, 2, 22);

Only, that gives us Tue Mar 22, 2011, 00:00:00 GMT+0000 (Greenwich Mean Time). That's because months in JavaScript start counting from 0, so February is 1, not 2:

 
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 NaN, but you'd be wrong. JavaScript skips to March 3rd! Since February only has 28 days in 2011, and there are three extra days, these days are added to the end of the month. In other words, you can't trust Date to return errors on all incorrect dates.

Strings Are Not Parsed to Numbers

The weirdest behavior is when we don't give JavaScript entire strings in parse. For example:

 
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.

Number Times Are Affected by the Time Zone

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

 
console.log(new Date(0));

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.

Years Are Inconsistent

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.

Why Doesn't Anyone Fix JavaScript Dates?

The JavaScript Date function is fundamentally broken in many ways - which is why most people use tools like Moment.js, but why hasn't it been fixed?

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.

To remedy this situation, JavaScript is introducing a new set of Temporal standards, which will occupy a different namespace than Date and solve most of the problems described in this article. Until then, we are stuck with the quirks JavaScript Dates produce. 

JavaScript programming langauge

Published at DZone with permission of Johnny Simpson, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • Segmentation Violation and How Rust Helps Overcome It
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!