You don't (may not) need Moment.js
Moment.js is a fantastic time & date library with lots of great features and utilities. However, if you are working on a performance sensitive web application, it might cause a huge performance overhead because of its complex APIs and large bundle size.
Problems with Moment.js:
If you are not using timezone but only a few simple functions from moment.js, this might bloat your app, and therefore is considered overkill. dayjs has a smaller core and has very similar APIs so it makes it very easy to migrate. date-fns enables tree-shaking and other benefits so that it works great with React, Sinon.js, and webpack, etc. See https://github.com/moment/moment/issues/2373 for more ideas on why and how people switch from moment.js to other solutions.
Brief Comparison
Name | Size original/gzipped | Tree-shaking | Popularity (stars) | Methods richness | Pattern | Timezone Support | Locale |
---|
Moment.js | 329K/69.6K | No | 43.4k | High | OO | Good (moment-timezone) | 123 |
Luxon | 59.9K/17.2K | No | 9k | High | OO | Good (Intl) | - |
date-fns | 78.4k/13.4k without tree-shaking | Yes | 21.3k | High | Functional | Good (date-fns-tz) | 64 |
dayjs | 6.5k/2.6k without plugins | No | 25.8k | High | OO | Not yet | 130 |
Voice of Developers
Removed moment.js to replace with date-fns - build output reduced by 40%
—Jared Farago from webnode project.
Good library if you’re looking to replace Moment.js for one reason or another. Immutable too.
—Dan Abramov, Author of Redux and co-author of Create React App. Building tools for humans.
I strongly recommend using date-fns over Moment.js, it's has a nicer API and you can include only parts you need!
—Matija Marohnić, a design-savvy frontend developer from Croatia.
Just yesterday changed momentjs to this lib in out project. Cut the size of our js bundle almost in half 😱
—Sergey Petushkov, a javaScript developer from Moscow, Russia • Currently in Berlin, Germany.
ESLint Plugin
If you're using ESLint, you can install a
plugin that
will help you identify places in your codebase where you don't (may not) need Moment.js.
Install the plugin...
npm install --save-dev eslint-plugin-you-dont-need-momentjs
...then update your config
"extends" : ["plugin:you-dont-need-momentjs/recommended"],
Quick Links
Parse
- String + Date Format
- String + Time Format
- String + Format + locale
Get + Set
- Millisecond/Second/Minute/Hour
- Date of Month
- Day of Week
- Day of Year
- Week of Year
- Days in Month
- Weeks in Year
- Maximum of the given dates
- Minimum of the given dates
Manipulate
- Add
- Subtract
- Start of Time
- End of Time
Display
- Format
- Time from now
- Time from X
- Difference
Query
- Is Before
- Is Same
- Is After
- Is Between
- Is Leap Year
- Is a Date
Feature Parity
⚠️ Indicates other packages or work are needed. See individual functions above.
| Native | Luxon | date-fns | dayjs |
---|
Parse | | | | |
String + Date Format | ✅ | ✅ | ✅ | ✅ |
String + Time Format | ✅ | ✅ | ✅ | ⚠️ |
String + Format + locale | ❌ | ⚠️ | ✅ | ⚠️ |
| | | | |
Get + Set | | | | |
Millisecond/Second/Minute/Hour | ✅ | ✅ | ✅ | ✅ |
Date of Month | ✅ | ✅ | ✅ | ✅ |
Day of Week | ✅ | ✅ | ✅ | ✅ |
Day of Year | ✅ | ✅ | ✅ | ✅ |
Week of Year | ✅ | ✅ | ✅ | ⚠️ |
Days in Month | ✅ | ✅ | ✅ | ✅ |
Weeks in Year | ❌ | ❌ | ✅ | ⚠️ |
Maximum of the given dates | ✅ | ✅ | ✅ | ⚠️ |
Minimum of the given dates | ✅ | ✅ | ✅ | ⚠️ |
| | | | |
Manipulate | | | | |
Add | ✅ | ✅ | ✅ | ✅ |
Subtract | ✅ | ✅ | ✅ | ✅ |
Start of Time | ❌ | ✅ | ✅ | ✅ |
End of Time | ✅ | ✅ | ✅ | ✅ |
| | | | |
Display | | | | |
Format | ❌ | ✅ | ✅ | ✅ |
Time from now | ❌ | ❌ | ✅ | ⚠️ |
Time from X | ❌ | ❌ | ✅ | ⚠️ |
Difference | ✅ | ✅ | ✅ | ✅ |
| | | | |
Query | | | | |
Is Before | ✅ | ✅ | ✅ | ✅ |
Is Same | ✅ | ✅ | ✅ | ✅ |
Is After | ✅ | ✅ | ✅ | ✅ |
Is Between | ❌ | ✅ | ✅ | ⚠️ |
Is Leap Year | ✅ | ✅ | ✅ | ⚠️ |
Is a Date | ✅ | ✅ | ✅ | ✅ |
Parse
String + Date Format
Return the date parsed from date string using the given format string.
moment('12-25-1995', 'MM-DD-YYYY');
const datePattern = /^(\d{2})-(\d{2})-(\d{4})$/;
const [, month, day, year] = datePattern.exec('12-25-1995');
new Date(`${month}, ${day} ${year}`);
import parse from 'date-fns/parse';
parse('12-25-1995', 'MM-dd-yyyy', new Date());
dayjs('12-25-1995');
DateTime.fromFormat('12-25-1995', 'MM-dd-yyyy').toJSDate();
⬆ back to top
String + Time Format
Return the date parsed from time string using the given format string.
moment('2010-10-20 4:30', 'YYYY-MM-DD HH:mm');
const datePattern = /^(\d{4})-(\d{2})-(\d{2})\s(\d{1,2}):(\d{2})$/;
const [, year, month, day, rawHour, min] = datePattern.exec('2010-10-20 4:30');
new Date(`${year}-${month}-${day}T${('0' + rawHour).slice(-2)}:${min}:00`);
import parse from 'date-fns/parse';
parse('2010-10-20 4:30', 'yyyy-MM-dd H:mm', new Date());
import customParseFormat from 'dayjs/plugin/customParseFormat';
dayjs.extend(customParseFormat);
dayjs('2010-10-20 4:30', 'YYYY-MM-DD HH:mm');
DateTime.fromFormat('2010-10-20 4:30', 'yyyy-MM-dd H:mm').toJSDate();
⬆ back to top
String + Format + locale
Return the date parsed from string using the given format string and locale.
moment('2012 mars', 'YYYY MMM', 'fr');
import parse from 'date-fns/parse';
import fr from 'date-fns/locale/fr';
parse('2012 mars', 'yyyy MMMM', new Date(), { locale: fr });
import customParseFormat from 'dayjs/plugin/customParseFormat';
import 'dayjs/locale/fr';
dayjs.extend(customParseFormat);
dayjs('2012 mars', 'YYYY MMM', 'fr');
DateTime.fromFormat('2012 mars', 'yyyy MMMM', { locale: 'fr' });
⬆ back to top
Get + Set
Millisecond / Second / Minute / Hour
Get the Millisecond/Second/Minute/Hour
of the given date.
moment().seconds();
moment().hours();
new Date().getSeconds();
new Date().getHours();
import getSeconds from 'date-fns/getSeconds';
import getHours from 'date-fns/getHours';
getSeconds(new Date());
getHours(new Date());
dayjs().second();
dayjs().hour();
DateTime.local().second;
DateTime.local().hour;
Performance tests
Library | Time |
---|
Moment | 1500.703ms |
Native | 348.411ms |
DateFns | 520.670ms |
DayJs | 494.234ms |
Luxon | 1208.368ms |
Set the Millisecond/Second/Minute/Hour
of the given date.
moment().seconds(30);
moment().hours(13);
new Date(new Date().setSeconds(30));
new Date(new Date().setHours(13));
import setSeconds from 'date-fns/setSeconds';
import setHours from 'date-fns/setHours';
setSeconds(new Date(), 30);
setHours(new Date(), 13);
dayjs().set('second', 30);
dayjs().set('hour', 13);
DateTime.utc()
.set({ second: 30 })
.toJSDate();
DateTime.utc()
.set({ hour: 13 })
.toJSDate();
Performance tests
Library | Time |
---|
Moment | 1689.744ms |
Native | 636.741ms |
DateFns | 714.148ms |
DayJs | 2037.603ms |
Luxon | 2897.571ms |
⬆ back to top
Date of Month
Gets or sets the day of the month.
moment().date();
moment().date(4);
new Date().getDate();
new Date().setDate(4);
import getDate from 'date-fns/getDate';
import setDate from 'date-fns/setDate';
getDate(new Date());
setDate(new Date(), 4);
dayjs().date();
dayjs().set('date', 4);
DateTime.utc().day;
DateTime.utc()
.set({ day: 4 })
.toString();
Performance tests
Library | Time |
---|
Moment | 1381.669ms |
Native | 397.415ms |
DateFns | 588.004ms |
DayJs | 1218.025ms |
Luxon | 2705.606ms |
⬆ back to top
Day of Week
Gets or sets the day of the week.
moment().day();
moment().day(-14);
new Date().getDay();
new Date().setDate(new Date().getDate() - 14);
import getDay from 'date-fns/getDay';
import setDay from 'date-fns/setDay';
getDay(new Date());
setDay(new Date(), -14);
dayjs().day();
dayjs().set('day', -14);
DateTime.local().weekday;
DateTime.local()
.minus({ day: 14 })
.toJSDate();
Library | Time |
---|
Moment | 1919.404ms |
Native | 543.466ms |
DateFns | 841.436ms |
DayJs | 1229.475ms |
Luxon | 3936.282ms |
⬆ back to top
Day of Year
Gets or sets the day of the year.
moment().dayOfYear();
moment().dayOfYear(256);
Math.floor(
(new Date() - new Date(new Date().getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24
);
import getDayOfYear from 'date-fns/getDayOfYear';
import setDayOfYear from 'date-fns/setDayOfYear';
getDayOfYear(new Date());
setDayOfYear(new Date(), 256);
import dayOfYear from 'dayjs/plugin/dayOfYear';
dayjs.extend(dayOfYear);
dayjs().dayOfYear();
dayjs().dayOfYear(256);
DateTime.local().ordinal;
DateTime.local()
.set({ ordinal: 256 })
.toString();
Library | Time |
---|
Moment | 5511.172ms |
Native | 530.592ms |
DateFns | 2079.043ms |
DayJs | - |
Luxon | 3540.810ms |
⬆ back to top
Week of Year
Gets or sets the week of the year.
moment().week();
moment().week(24);
import getWeek from 'date-fns/getWeek';
import setWeek from 'date-fns/setWeek';
getWeek(new Date());
setWeek(new Date(), 24);
const day = new Date();
const MILLISECONDS_IN_WEEK = 604800000;
const firstDayOfWeek = 1;
const startOfYear = new Date(day.getFullYear(), 0, 1);
startOfYear.setDate(
startOfYear.getDate() + (firstDayOfWeek - (startOfYear.getDay() % 7))
);
const dayWeek = Math.round((day - startOfYear) / MILLISECONDS_IN_WEEK) + 1;
const day = new Date();
const week = 24;
const MILLISECONDS_IN_WEEK = 604800000;
const firstDayOfWeek = 1;
const startOfYear = new Date(day.getFullYear(), 0, 1);
startOfYear.setDate(
startOfYear.getDate() + (firstDayOfWeek - (startOfYear.getDay() % 7))
);
const dayWeek = Math.round((day - startOfYear) / MILLISECONDS_IN_WEEK) + 1;
day.setDate(day.getDate() - (dayWeek - week) * 7);
day.toISOString();
import weekOfYear from 'dayjs/plugin/weekOfYear';
dayjs.extend(weekOfYear);
dayjs().week();
dayjs().week(24);
DateTime.local().weekNumber;
DateTime.local()
.set({ weekNumber: 23 })
.toString();
Library | Time |
---|
Moment | 7147.201ms |
Native | 1371.631ms |
DateFns | 5834.815ms |
DayJs | - |
Luxon | 4514.771ms |
⬆ back to top
Days in Month
Get the number of days in the current month.
moment('2012-02', 'YYYY-MM').daysInMonth();
new Date(2012, 02, 0).getDate();
import getDaysInMonth from 'date-fns/getDaysInMonth';
getDaysInMonth(new Date(2012, 1));
dayjs('2012-02').daysInMonth();
DateTime.local(2012, 2).daysInMonth;
Library | Time |
---|
Moment | 4415.065ms |
Native | 186.196ms |
DateFns | 634.084ms |
DayJs | 1922.774ms |
Luxon | 1403.032ms |
⬆ back to top
Weeks in Year
Gets the number of weeks in the current year, according to ISO weeks.
moment().isoWeeksInYear();
import getISOWeeksInYear from 'date-fns/getISOWeeksInYear';
getISOWeeksInYear(new Date());
import isoWeeksInYear from 'dayjs/plugin/isoWeeksInYear';
dayjs.extend(isoWeeksInYear);
dayjs().isoWeeksInYear();
DateTime.local().weeksInWeekYear;
Library | Time |
---|
Moment | 1065.247ms |
Native | - |
DateFns | 4954.042ms |
DayJs | - |
Luxon | 1134.483ms |
⬆ back to top
Maximum of the given dates
Returns the maximum (most distant future) of the given date.
const array = [
new Date(2017, 4, 13),
new Date(2018, 2, 12),
new Date(2016, 0, 10),
new Date(2016, 0, 9),
];
moment.max(array.map(a => moment(a)));
new Date(Math.max.apply(null, array)).toISOString();
import max from 'date-fns/max';
max(array);
import minMax from 'dayjs/plugin/minMax';
dayjs.extend(minMax);
dayjs.max(array.map(a => dayjs(a)));
DateTime.max(...array.map(a => DateTime.fromJSDate(a))).toJSDate();
Library | Time |
---|
Moment | 1780.075ms |
Native | 828.332ms |
DateFns | 980.938ms |
DayJs | - |
Luxon | 2694.702ms |
⬆ back to top
Minimum of the given dates
Returns the minimum (most distant future) of the given date.
const array = [
new Date(2017, 4, 13),
new Date(2018, 2, 12),
new Date(2016, 0, 10),
new Date(2016, 0, 9),
];
moment.min(array.map(a => moment(a)));
new Date(Math.min.apply(null, array)).toISOString();
import min from 'date-fns/min';
min(array);
import minMax from 'dayjs/plugin/minMax';
dayjs.extend(minMax);
dayjs.min(array.map(a => dayjs(a)));
DateTime.min(...array.map(a => DateTime.fromJSDate(a))).toJSDate();
Library | Time |
---|
Moment | 1744.459ms |
Native | 819.646ms |
DateFns | 841.249ms |
DayJs | - |
Luxon | 2720.462ms |
⬆ back to top
Manipulate
Add
Add the specified number of days to the given date.
moment().add(7, 'days');
const now = new Date();
now.setDate(now.getDate() + 7);
import addDays from 'date-fns/addDays';
addDays(new Date(), 7);
dayjs().add(7, 'day');
DateTime.local()
.plus({ day: 7 })
.toJSDate();
Library | Time |
---|
Moment | 1309.485ms |
Native | 259.932ms |
DateFns | 385.394ms |
DayJs | 1911.881ms |
Luxon | 3919.797ms |
⬆ back to top
Subtract
Subtract the specified number of days from the given date.
moment().subtract(7, 'days');
new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 7);
import subDays from 'date-fns/subDays';
subDays(new Date(), 7);
dayjs().subtract(7, 'day');
DateTime.local()
.minus({ day: 7 })
.toJSDate();
Library | Time |
---|
Moment | 1278.384ms |
Native | 215.255ms |
DateFns | 379.057ms |
DayJs | 1772.593ms |
Luxon | 4028.866ms |
⬆ back to top
Start of Time
Return the start of a unit of time for the given date.
moment().startOf('month');
import startOfMonth from 'date-fns/startOfMonth';
startOfMonth(new Date());
dayjs().startOf('month');
DateTime.local().startOf('month');
Library | Time |
---|
Moment | 1078.948ms |
Native | - |
DateFns | 398.107ms |
DayJs | 765.358ms |
Luxon | 2306.765ms |
⬆ back to top
End of Time
Return the end of a unit of time for the given date.
moment().endOf('day');
const end = new Date();
end.setHours(23, 59, 59, 999);
end.toISOString();
import endOfDay from 'date-fns/endOfDay';
endOfDay(new Date());
dayjs().endOf('day');
DateTime.local().endOf('day');
Library | Time |
---|
Moment | 1241.304ms |
Native | 225.519ms |
DateFns | 319.773ms |
DayJs | 914.425ms |
Luxon | 9920.529ms |
⬆ back to top
Display
Format
Return the formatted date string in the given format.
moment().format('dddd, MMMM Do YYYY, h:mm:ss A');
moment().format('ddd, hA');
import format from 'date-fns/format';
format(new Date(), 'eeee, MMMM do YYYY, h:mm:ss aa');
format(new Date(), 'eee, ha');
dayjs().format('dddd, MMMM D YYYY, h:mm:ss A');
dayjs().format('ddd, hA');
import advancedFormat from 'dayjs/plugin/customParseFormat';
dayjs.extend(advancedFormat);
dayjs().format('dddd, MMMM Do YYYY, h:mm:ss A');
DateTime.fromMillis(time).toFormat('EEEE, MMMM dd yyyy, h:mm:ss a');
DateTime.fromMillis(time).toFormat('EEE, ha');
⬆ back to top
Time from now
Return time from now.
moment(1536484369695).fromNow();
import formatDistance from 'date-fns/formatDistance';
formatDistance(new Date(1536484369695), new Date(), { addSuffix: true });
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
dayjs(1536484369695).fromNow();
⬆ back to top
Time from x
Return time from x.
moment([2007, 0, 27]).to(moment([2007, 0, 29]));
import formatDistance from 'date-fns/formatDistance';
formatDistance(new Date(2007, 0, 27), new Date(2007, 0, 29));
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
dayjs('2007-01-27').to(dayjs('2007-01-29'));
⬆ back to top
Difference
Get the unit of time between the given dates.
moment([2007, 0, 27]).diff(moment([2007, 0, 29]));
moment([2007, 0, 27]).diff(moment([2007, 0, 29]), 'days');
new Date(2007, 0, 27) - new Date(2007, 0, 29);
Math.ceil(
(new Date(2007, 0, 27) - new Date(2007, 0, 29)) / 1000 / 60 / 60 / 24
);
import differenceInMilliseconds from 'date-fns/differenceInMilliseconds';
differenceInMilliseconds(new Date(2007, 0, 27), new Date(2007, 0, 29));
import differenceInDays from 'date-fns/differenceInDays';
differenceInDays(new Date(2007, 0, 27), new Date(2007, 0, 29));
dayjs('2007-01-27').diff(dayjs('2007-01-29'), 'milliseconds');
dayjs('2007-01-27').diff(dayjs('2007-01-29'), 'days');
DateTime.local(2007, 1, 27).diff(DateTime.local(2007, 1, 29)).milliseconds;
DateTime.local(2007, 1, 27).diff(DateTime.local(2007, 1, 29), 'days').days;
⬆ back to top
Query
Is Before
Check if a date is before another date.
moment('2010-10-20').isBefore('2010-10-21');
new Date(2010, 10, 20) < new Date(2010, 10, 21);
import isBefore from 'date-fns/isBefore';
isBefore(new Date(2010, 9, 20), new Date(2010, 9, 21));
dayjs('2010-10-20').isBefore('2010-10-21');
DateTime.fromISO('2010-10-20') < DateTime.fromISO('2010-10-21');
⬆ back to top
Is Same
Check if a date is the same as another date.
moment('2010-10-20').isSame('2010-10-21');
moment('2010-10-20').isSame('2010-10-20');
moment('2010-10-20').isSame('2010-10-21', 'month');
new Date(2010, 9, 20).valueOf() === new Date(2010, 9, 21).valueOf();
new Date(2010, 9, 20).valueOf() === new Date(2010, 9, 20).valueOf();
new Date(2010, 9, 20).getTime() === new Date(2010, 9, 20).getTime();
new Date(2010, 9, 20).valueOf() === new Date(2010, 9, 20).getTime();
new Date(2010, 9, 20).toDateString().substring(4, 7) ===
new Date(2010, 9, 21).toDateString().substring(4, 7);
import isSameDay from 'date-fns/isSameDay';
import isSameMonth from 'date-fns/isSameMonth';
isSameDay(new Date(2010, 9, 20), new Date(2010, 9, 21));
isSameDay(new Date(2010, 9, 20), new Date(2010, 9, 20));
isSameMonth(new Date(2010, 9, 20), new Date(2010, 9, 21));
dayjs('2010-10-20').isSame('2010-10-21');
dayjs('2010-10-20').isSame('2010-10-20');
dayjs('2010-10-20').isSame('2010-10-21', 'month');
(+DateTime.fromISO('2010-10-20') ===
+DateTime.fromISO('2010-10-21') +
DateTime.fromISO('2010-10-20')) ===
+DateTime.fromISO('2010-10-20');
DateTime.fromISO('2010-10-20').hasSame(DateTime.fromISO('2010-10-21'), 'month');
⬆ back to top
Is After
Check if a date is after another date.
moment('2010-10-20').isAfter('2010-10-19');
new Date(2010, 9, 20) > new Date(2010, 9, 19);
import isAfter from 'date-fns/isAfter';
isAfter(new Date(2010, 9, 20), new Date(2010, 9, 19));
dayjs('2010-10-20').isAfter('2010-10-19');
DateTime.fromISO('2010-10-20') > DateTime.fromISO('2010-10-19');
⬆ back to top
Is Between
Check if a date is between two other dates.
moment('2010-10-20').isBetween('2010-10-19', '2010-10-25');
import isWithinInterval from 'date-fns/isWithinInterval';
isWithinInterval(new Date(2010, 9, 20), {
start: new Date(2010, 9, 19),
end: new Date(2010, 9, 25),
});
import isBetween from 'dayjs/plugin/isBetween';
dayjs.extend(isBetween);
dayjs('2010-10-20').isBetween('2010-10-19', '2010-10-25');
Interval.fromDateTimes(
DateTime.fromISO('2010-10-19'),
DateTime.fromISO('2010-10-25')
).contains(DateTime.fromISO('2010-10-20'));
⬆ back to top
Is Leap Year
Check if a year is a leap year.
moment([2000]).isLeapYear();
new Date(2000, 1, 29).getDate() === 29;
import isLeapYear from 'date-fns/isLeapYear';
isLeapYear(new Date(2000, 0, 1));
import isLeapYear from 'dayjs/plugin/isLeapYear';
dayjs.extend(isLeapYear);
dayjs('2000-01-01').isLeapYear();
expect(DateTime.local(2000).isInLeapYear).toBeTruthy();
⬆ back to top
Is a Date
Check if a variable is a native js Date object.
moment.isDate(new Date());
new Date() instanceof Date;
import isDate from 'date-fns/isDate';
isDate(new Date());
dayjs(new Date()).isValid();
DateTime.local().isValid;
⬆ back to top
License
MIT