Rules of parsing dates with Date.parse
Rule of thumb: do not use it!
One of the projects I’ve been working on recently is resume.io — online resume builder. We have built the web service from the ground up and so far it is one of the best experiences I’ve ever had as a developer. However some strange emails appeared in our support inbox recently. People were complaining that they couldn’t change dates of their work experience and that «the system keeps changing correct dates on its own».
I tried to reproduce the bug several times, I even tested it in the exact same environment (luckily you don’t have to keep virtual machine on your laptop anymore for it) but it was hopeless — the interface was working as it supposed to do. I noticed that those emails were mostly from US users so I made a quick guess that it somehow might be related to their timezone. So it was!
Our application was built on React/Redux with Redux Form and we wrote a custom <Field /> component for date ranges. Except for normal dates we needed to handle special cases like «don’t show the date» or «show year only» so we used an adapter that would transform the data into UI-friendly format and transform it back when the value is changed. It is quite convenient for testing and luckily (or unfortunately) leads to some funny results if one piece of the transformation is broken.
So what was the problem?
It turned out we passed dates as “2016–10–01” strings from our Rails-backend to Date.parse function:
MDN warns us that the use of this function is not recommended because it is browser-specific and may cause unexpected behaviour.
The reason is because browsers treat timezone here in a different way. For example, Chrome and Safari assume that the time is given in UTC, whereas others are expecting it to be in local format. Try to extract the day of month and you will notice the difference.
The irony: because our dev team is located in Moscow’s timezone (it’s GMT+03 and Date.parse always gives us the same day) we simply couldn’t spot the bug in a first place.
How to avoid those awful mistakes in the future?
You should never use Date.parse function. There is a version of Date constructor that takes year, month and day integers instead:
Finally, consider using timestamps but what is most important — write acceptance tests for your interfaces.
We’ve been lucky enough not to lose our clients because of this bug, however there is still some deep irritation left after this case. Because of the new tests this error won’t occur in our project and because of this article you can avoid it in yours. Cheers! 🤓
About the author
Married, has three cats.