This week in JavaScript - 31/01/2025
Over the last few months, I’ve moved more into the JavaScript / TypeScript realm at Edozo. This has been exciting for me, as it’s the first time I’ve written production, user facing, JavaScript code in “anger”. Sure, I’ve written code for loads of developers when I was at Rightmove, from Groovy, to Bash, to even a little bit of Kotlin. But for the most part, my core has been Java and writing code serverside.
With that in mind, I thought I’d start a new semi-regular column called “This week in JavaScript”, where I share some of the interesting things I’ve found.
So, without further ado…
Date() in JavaScript is not friendly
Dates are not nice to work with in JavaScript. The core library was written based on the very early implementation of Java. Which since then Java has rewritten its Date implementation twice. So essentially JS developers are working with something designed 30 years ago… Ouch. With that in mind, I thought I’d share three interesting things that you might not know about Dates in JS.
1. Months start at 0
This is actually quite common across older languages. I found both C and C++ does this, as well as the original Java date Implementation.
When using date.getMonth()
you’ll get 0 for January, 1 for February, and so on. Which can be a little confusing.
It also leads to code like:
const givenMonthFromUserInput = 12; // where they've inputted December
new Date().setMonth(givenMonthFromUserInput - 1)
Which can seem a little wonky.
More modern languages like Rust, C#, GO, and now Java, all start at 1. Which is a fair bit more human readable
2. date.setMonth() is “dangerous”
Ok, so dangerous might be a little strong, but oh boy did this surprise me this week. I think I’ll need an example.
You’ve been given a date for November, broken down into an array; [23,11,2024]
So, you might do:
const given = [21, 11, 2024];
const date = new Date();
date.setDate(given[0]);
date.setMonth(given[1] - 1);
date.setFullYear(given[2]);
// expected
// 2024-11-21T17:15:57.213Z (with the current time attached)
Which is exactly how I thought I would work. And it mostly does, except on specific days.
Lets say today is the 31st of January.
In the documentation for .setMonth()
is an extra parameter. Here’s it from MDN :
monthValue
An integer representing the month: 0 for January, 1 for February, and so on.
dateValue (Optional)
An integer from 1 to 31 representing the day of the month.
That Optional dateValue
is the problem here. It has a weird little side effect where if you don’t provide it, it’ll use todays date.
Lets take a look at the above example again:
// Remember, "today" is the 31st of January
const given = [21, 11, 2024];
const date = new Date();
date.setDate(given[0]);
date.setMonth(given[1] - 1);
date.setFullYear(given[2]);
// actual
// 2024-12-21T17:15:57.213Z - The month now states DECEMBER!
2024-12-21 - December? huh?!
Why is this? Well, if you don’t provide a dateValue
, it will use todays date (which in this scenario, is the 31st). But there isn’t 31 days in November, so JS decides to roll over to the next Month. And Tada! You’ve now got December.
This is actually true for all date stuff in JS. Setting a month to 15 for example will actually roll the year over.
Something to watch out for, if you’re ever building dates.
3. Date Libraries & The Future
Of course, there are hundreds of blogposts complaining about JavaScripts Date
. It’s well known source of pain. So of course there are libraries out there that will help you handle these quirks.
A quick Google Duck Duck Go usually pops up with Moment.js, however this seems to be in maintenance mode and is also little “chunky”. So while it’s well talked about, it might no longer be an appropriate library for your needs.
If you’re more familiar with Java LocalDateTime
, it might be worth looking at js-joda. It’s API’s are very similar to what was introduced in Java 8. Though if you’re a pure JS dev, this might not be much of a bonus.
Then there’s the new Temporal implementation coming. This is baked into the language, and is slowly being shipped with browsers. While it’s probably going to be a few years before it becomes ubiquitous, its exciting that after 30 years JS is catching up with the times. Oh, and months start at 1 in Temporal 👍.