Moment.js is an awesome library when it comes to performing complex date-time manipulations. It provides a rich and clean API that covers many use cases. That aside, Moment.js shouldn’t always be the go-to library when it comes to date-time problematics. Alternatives should be considered as well.
Actually, there are plenty of alternatives out there:
This decision bases on two reasons:
- Lightweight – only 2.6KB gzip
- Similar API to Moment.js – which means easier migration
All date-time functions used in our apps are located in the service
date.service.ts. So the migration of this service made the switch possible for us.
In general, having the date-time manipulation centralised in one place is a good practice. It makes changes like this one possible without much effort.
- Make sure that the service is 100% covered with unit tests
- Check if all Moment.js API usages are available in Day.js
- Replace Moment.js with Day.js in the
- Adjust the service to use Day.js
Step 1. was an easy one. We just wrote the missing unit tests for our service.
In general, test coverage of utility functions should always be high.
In Step 2. we found out that the following changes were necessary:
- Object instantiation
// Moment.js const now = moment(); const day = moment('2019-07-12');
// Day.js const now = dayjs(); const day = dayjs('2019-07-12');
- Second parameter in
diffis plural in Moment.js, but singular in Day.js
// Moment.js var date1 = moment('2019-07-11'); var date2 = moment('2019-07-10'); date1.diff(date2, 'years'); // 0 date1.diff(date2, 'days'); // 1
// Day.js const date1 = dayjs('2019-07-11'); const date2 = dayjs('2019-07-10'); date1.diff(date2, 'year'); // 0 date1.diff(date2, 'day'); // 1
- UTC support doesn’t come out of the box with Day.js
- dayjs-plugin-utc should be installed
// Moment.js moment('2019-07-12T15:37:01+02:00').utc().format(); //2019-07-12T13:37:01Z
// Day.js import dayjsPluginUTC from 'dayjs-plugin-utc'; dayjs.extend(dayjsPluginUTC); dayjs('2019-07-12T15:37:01+02:00').utc().format(); //2019-07-12T13:37:01Z
months()doesn’t exists in Day.js
// Moment.js moment.months(); // ['January', 'February', ... , 'December' ]
// Day.js dayjs.months(); // dayjs.months is not a function
The APIs are mostly compatible. Finding these key differences between the libraries helped us to tackle all the issues in Step 3 and 4.
All other changes were specifically related to our business logic.
The migration confirmed our intentions. Our bundle is 60KB (~10%) lighter.
Gzipped size of Moment.js was 72.47KB and now of Day.js is 3.14KB (including locale and UTC plugin)
So far, switching to Day.js seems like a great decision. We haven’t run into any issues since our migration, one month ago.
The goal of this blog post is not to convince you that Day.js is awesome and Moment.js is terrible. But to remind you that choosing a date-time library is not an easy task.
There are many options available, so take your time and find out which one might be the best for your apps and needs.
Part of ottonova’s Software Engineering team since the very beginning.
Always on the lookout to improve our teams and to take the next step.
Clean code and KISS evangelist.