There’s a joke that there are three hard problems in software development:
1. Naming things
2. Off by one
I’m currently working on a project built with NextJS, utilizing Material UI components and date-fns functions. Because we are building for end users in different parts of the world, we consider time zones and localization.
Now, the second difficult problem every software developer has to solve is showing up for me: dates being off by one. Here’s how the bug report comes in. The user is in Asia time and tries to create an entry with a manual selection of date. Upon successfully submitting the entry, they see a date that is one day off from what they have selected. I take a look at our date creation and forms, and immediately, the standard new Date()
stands out to me. Ah, of course! This new Date()
is localized to the user’s local time, and when we parse it as UTC, it’s off. But as I debug, there seem to be multiple traps I have set up for this date creation. For our project entries, the time didn’t matter. It was purely the date, so not localizing was essential. Here are three gotchas I found along the way.
Material UI Date Picker Localizes Date String
If you pass in a string
into the date picker rather than the date object, the date picker will create a new date that is localized. The tip here is to always pass a date into your date picker.
NextJS Server to Client Date Parsing
When a date is passed from the server side of NextJS to the client side, it will also create a new date and get localized if it’s a date object. The tip here is to always pass dates as strings between the server and client side.
Date Creation
To ensure that we weren’t localizing upon date creation, date-fns has a great parse function. We created a new function just for creating dates that takes a string, and in it was parse(dateString, 'yyyy-mm-dd', new Date());
. This worked for us because our project entries did not care for time, only the date.
This isn’t a comprehensive view on fixing all of the off-by-one-date problems out there, but I definitely learned a couple things that will keep me from repeating these traps for future date bugs.