You-Dont-Need-Momentjs
List of functions which you can use to replace moment.js + ESLint Plugin
Top Related Projects
⏳ Modern JavaScript date utility library ⌛️
⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API
A tiny (349B) reusable date formatter. Extremely fast!
⏱ A library for working with dates and times in JS
Tiny millisecond conversion utility
Quick Overview
You-Dont-Need-Momentjs is a GitHub repository that provides alternatives to the popular Moment.js library using native JavaScript Date objects and modern ES6+ features. It aims to help developers reduce bundle size and improve performance by avoiding the use of Moment.js when simpler solutions are available.
Pros
- Reduces bundle size by eliminating the need for a large external library
- Improves performance by using native JavaScript methods
- Encourages the use of modern JavaScript features and best practices
- Provides a comprehensive list of alternatives for common Moment.js operations
Cons
- May require more code for complex date manipulations compared to Moment.js
- Lacks some of the advanced features and localization options available in Moment.js
- Might not be suitable for projects that heavily rely on Moment.js-specific functionality
- Requires developers to have a good understanding of JavaScript Date objects and ES6+ features
Code Examples
- Parsing dates:
// Instead of moment('2019-01-25')
const date = new Date('2019-01-25');
- Formatting dates:
// Instead of moment().format('YYYY-MM-DD')
const date = new Date();
const formattedDate = date.toISOString().slice(0, 10);
- Adding/subtracting time:
// Instead of moment().add(7, 'days')
const date = new Date();
date.setDate(date.getDate() + 7);
Getting Started
To start using native JavaScript alternatives to Moment.js:
- Remove Moment.js from your project dependencies.
- Refer to the You-Dont-Need-Momentjs repository for specific alternatives to Moment.js functions.
- Use native JavaScript Date objects and methods in your code.
- For more complex operations, consider using smaller, focused libraries or writing custom utility functions.
Example:
// Replace Moment.js import
// import moment from 'moment';
// Use native JavaScript
const now = new Date();
const formattedDate = now.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(formattedDate); // Output: March 15, 2023 (example)
Competitor Comparisons
⏳ Modern JavaScript date utility library ⌛️
Pros of date-fns
- Modular architecture allows for tree-shaking and smaller bundle sizes
- Immutable and pure functions, making it more predictable and easier to test
- Supports a wide range of locales and time zones out of the box
Cons of date-fns
- Slightly more verbose syntax compared to native Date methods
- Requires importing individual functions, which can be less convenient for quick scripts
- Less established community and ecosystem compared to Moment.js alternatives
Code Comparison
date-fns:
import { format, addDays } from 'date-fns'
const date = new Date()
const formattedDate = format(date, 'yyyy-MM-dd')
const futureDate = addDays(date, 7)
You-Dont-Need-Momentjs (using native Date methods):
const date = new Date()
const formattedDate = date.toISOString().split('T')[0]
const futureDate = new Date(date.setDate(date.getDate() + 7))
Both libraries aim to provide alternatives to Moment.js, with date-fns offering a more comprehensive set of functions and better performance, while You-Dont-Need-Momentjs focuses on leveraging native JavaScript Date methods for common operations. The choice between them depends on project requirements, bundle size constraints, and developer preferences.
⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API
Pros of Day.js
- Lightweight and minimalistic, with a smaller bundle size
- Chainable API for more fluent and readable code
- Extensive plugin system for additional functionality
Cons of Day.js
- Less comprehensive out-of-the-box functionality compared to native Date methods
- May require additional plugins for advanced features, potentially increasing complexity
Code Comparison
You-Dont-Need-Momentjs:
const date = new Date('2019-01-25');
const formattedDate = date.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
Day.js:
import dayjs from 'dayjs';
const date = dayjs('2019-01-25');
const formattedDate = date.format('MMMM D, YYYY');
Both approaches achieve similar results, but Day.js offers a more concise and readable syntax for date formatting. However, You-Dont-Need-Momentjs leverages native JavaScript methods, which may be preferable in some cases for better performance and reduced dependencies.
The choice between the two depends on project requirements, bundle size constraints, and developer preferences. Day.js provides a more user-friendly API and extensive plugin ecosystem, while You-Dont-Need-Momentjs promotes using built-in JavaScript functionality for date manipulation.
A tiny (349B) reusable date formatter. Extremely fast!
Pros of tinydate
- Extremely lightweight (340 bytes gzipped) compared to the larger alternatives suggested in You-Dont-Need-Momentjs
- Simple API focused on date formatting, making it easy to use for basic date operations
- Zero dependencies, reducing potential security risks and maintenance overhead
Cons of tinydate
- Limited functionality compared to the native Date methods and other alternatives suggested in You-Dont-Need-Momentjs
- Lacks support for parsing dates or performing date calculations
- No built-in localization support, which may require additional code for international date formatting
Code Comparison
tinydate:
import tinydate from 'tinydate';
const stamp = tinydate('{YYYY}-{MM}-{DD}');
console.log(stamp(new Date()));
You-Dont-Need-Momentjs (using native Date):
const date = new Date();
const formatted = date.toISOString().slice(0, 10);
console.log(formatted);
Both examples achieve similar results, but tinydate offers a more customizable formatting approach, while You-Dont-Need-Momentjs promotes using native JavaScript Date methods for simplicity and better performance.
⏱ A library for working with dates and times in JS
Pros of Luxon
- Comprehensive API for date and time manipulation
- Immutable objects, preventing unintended side effects
- Built-in support for time zones and internationalization
Cons of Luxon
- Larger bundle size compared to native Date methods
- Steeper learning curve for developers new to the library
- May be overkill for simple date operations
Code Comparison
You-Dont-Need-Momentjs:
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
Luxon:
import { DateTime } from "luxon";
const today = DateTime.now();
const tomorrow = today.plus({ days: 1 });
Summary
Luxon offers a robust solution for complex date and time operations, especially when dealing with time zones and internationalization. However, for simpler use cases, the native JavaScript Date methods promoted by You-Dont-Need-Momentjs may be sufficient and more lightweight. The choice between the two depends on the specific requirements of your project and the complexity of date manipulations needed.
Tiny millisecond conversion utility
Pros of ms
- Lightweight and focused solely on time string parsing and conversion
- Simple API with a single function for both parsing and formatting
- Supports a wide range of time units and formats
Cons of ms
- Limited functionality compared to more comprehensive date libraries
- Lacks advanced date manipulation and calculation features
- No support for timezones or localization
Code Comparison
ms:
ms('2 days') // 172800000
ms('1d') // 86400000
ms(60000) // "1m"
You-Dont-Need-Momentjs:
const date = new Date();
date.setDate(date.getDate() + 2);
date.getTime() - new Date().getTime(); // 172800000
Summary
ms is a lightweight library focused on parsing and formatting time strings, while You-Dont-Need-Momentjs provides alternatives to Moment.js using native JavaScript Date objects. ms offers a simpler API for basic time conversions, but lacks advanced date manipulation features. You-Dont-Need-Momentjs demonstrates how to achieve similar functionality using built-in JavaScript methods, potentially reducing bundle size and dependencies. The choice between the two depends on the specific needs of your project and the level of date manipulation required.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
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:
- It is highly based on OOP APIs, which makes it fail to work with tree-shaking, thus leading to a huge bundle size and performance issues.
- It is mutable and it causes bugs:
- Complex OOP API (which doubles mutability problem). Here is an example:
https://github.com/moment/moment/blob/develop/src/test/moment/add_subtract.js#L244-L286
Moment.js allows to use
a.subtract('ms', 50)
,a.subtract(50, 'ms')
and evena.subtract('s', '50')
.
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 | Tree-shaking | Methods richness | Pattern | Locale | Timezone Support | Popularity (stars) | Sizes |
---|---|---|---|---|---|---|---|
Moment.js | No | High | OO | 123 | Good (moment-timezone) | ||
Luxon | No | High | OO | - | Good (Intl) | ||
date-fns | Yes | High | Functional | 64 | Good (date-fns-tz) | ||
dayjs | No | High | OO | 138 | Good (Intl) |
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.
—Matija MarohniÄ, a design-savvy frontend developer from Croatia.
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
- 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
Feature Parity
â ï¸ Indicates other packages or work are needed. See individual functions above.
Native | Luxon | date-fns | dayjs | Temporal | |
---|---|---|---|---|---|
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.js
moment('12-25-1995', 'MM-DD-YYYY');
// => "1995-12-24T13:00:00.000Z"
// Native
const datePattern = /^(\d{2})-(\d{2})-(\d{4})$/;
const [, month, day, year] = datePattern.exec('12-25-1995');
new Date(`${month}, ${day} ${year}`);
// => "1995-12-24T13:00:00.000Z"
// date-fns
import parse from 'date-fns/parse';
parse('12-25-1995', 'MM-dd-yyyy', new Date());
// => "1995-12-24T13:00:00.000Z"
// dayjs
dayjs('12-25-1995');
// => "1995-12-24T13:00:00.000Z"
// luxon
DateTime.fromFormat('12-25-1995', 'MM-dd-yyyy').toJSDate();
// => "1995-12-24T13:00:00.000Z"
// Temporal
const datePattern = /^(\d{2})-(\d{2})-(\d{4})$/;
const [, month, day, year] = datePattern.exec('12-25-1995');
new Temporal.ZonedDateTime.from({year, month, day, timeZone: Temporal.Now.timeZone()});
// => "1995-12-24T13:00:00.000Z"
String + Time Format
Return the date parsed from time string using the given format string.
// Moment.js
moment('2010-10-20 4:30', 'YYYY-MM-DD HH:mm');
// => "2010-10-19T17:30:00.000Z"
// Native
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`);
// => "2010-10-19T17:30:00.000Z"
// date-fns
import parse from 'date-fns/parse';
parse('2010-10-20 4:30', 'yyyy-MM-dd H:mm', new Date());
// => "2010-10-19T17:30:00.000Z"
// dayjs â ï¸ requires customParseFormat plugin
import customParseFormat from 'dayjs/plugin/customParseFormat';
dayjs.extend(customParseFormat);
dayjs('2010-10-20 4:30', 'YYYY-MM-DD HH:mm');
// => "2010-10-19T17:30:00.000Z"
// luxon
DateTime.fromFormat('2010-10-20 4:30', 'yyyy-MM-dd H:mm').toJSDate();
// => "2010-10-19T17:30:00.000Z"
// Temporal
const datePattern = /^(\d{4})-(\d{2})-(\d{2})\s(\d{1,2}):(\d{2})$/;
const [, year, month, day, hour, minute] = datePattern.exec('2010-10-20 4:30');
new Temporal.ZonedDateTime.from({year, month, day, hour, minute, timeZone: Temporal.Now.timeZone()});
// => "2010-10-19T17:30:00.000Z"
String + Format + locale
Return the date parsed from string using the given format string and locale.
// Moment.js
moment('2012 mars', 'YYYY MMM', 'fr');
// => "2012-02-29T13:00:00.000Z"
// date-fns
import parse from 'date-fns/parse';
import fr from 'date-fns/locale/fr';
parse('2012 mars', 'yyyy MMMM', new Date(), { locale: fr });
// => "2012-02-29T13:00:00.000Z"
// dayjs â ï¸ requires customParseFormat plugin
import customParseFormat from 'dayjs/plugin/customParseFormat';
import 'dayjs/locale/fr';
dayjs.extend(customParseFormat);
dayjs('2012 mars', 'YYYY MMM', 'fr');
// => "2012-02-29T13:00:00.000Z"
// Luxon â does not support Locale for node unless https://moment.github.io/luxon/docs/manual/install.html#node
DateTime.fromFormat('2012 mars', 'yyyy MMMM', { locale: 'fr' });
// => "2012-02-29T13:00:00.000Z"
Get + Set
Millisecond / Second / Minute / Hour
Get the Millisecond/Second/Minute/Hour
of the given date.
// Moment.js
moment().seconds();
// => 49
moment().hours();
// => 19
// Native
new Date().getSeconds();
// => 49
new Date().getHours();
// => 19
// date-fns
import getSeconds from 'date-fns/getSeconds';
import getHours from 'date-fns/getHours';
getSeconds(new Date());
// => 49
getHours(new Date());
// => 19
// dayjs
dayjs().second();
// => 49
dayjs().hour();
// => 19
// Luxon
DateTime.local().second;
// => 49
DateTime.local().hour;
// => 19
// Temporal
Temporal.Now.zonedDateTimeISO().second;
// => 49
Temporal.Now.zonedDateTimeISO().hour;
// => 19
Performance tests
Library | Time |
---|---|
Moment | 1500.703ms |
Native | 348.411ms |
DateFns | 520.670ms |
DayJs | 494.234ms |
Luxon | 1208.368ms |
Temporal | - |
Set the Millisecond/Second/Minute/Hour
of the given date.
// Moment.js
moment().seconds(30);
// => "2018-09-09T09:12:30.695Z"
moment().hours(13);
// => "2018-09-09T03:12:49.695Z"
// Native
new Date(new Date().setSeconds(30));
// => "2018-09-09T09:12:30.695Z"
new Date(new Date().setHours(13));
// => "2018-09-09T03:12:49.695Z"
// date-fns
import setSeconds from 'date-fns/setSeconds';
import setHours from 'date-fns/setHours';
setSeconds(new Date(), 30);
// => "2018-09-09T09:12:30.695Z"
setHours(new Date(), 13);
// => "2018-09-09T03:12:49.695Z"
// dayjs
dayjs().set('second', 30);
// => "2018-09-09T09:12:30.695Z"
dayjs().set('hour', 13);
// => "2018-09-09T03:12:49.695Z"
// luxon
DateTime.utc()
.set({ second: 30 })
.toJSDate();
// => "2018-09-09T09:12:30.695Z"
DateTime.utc()
.set({ hour: 13 })
.toJSDate();
// => "2018-09-09T03:12:49.695Z"
// Temporal
Temporal.Now.zonedDateTimeISO().with({ second: 30 });
// => "2018-09-09T09:12:30.695Z"
Temporal.Now.zonedDateTimeISO().with({ hour: 13 });
// => "2018-09-09T03:12:49.695Z"
Performance tests
Library | Time |
---|---|
Moment | 1689.744ms |
Native | 636.741ms |
DateFns | 714.148ms |
DayJs | 2037.603ms |
Luxon | 2897.571ms |
Temporal | - |
Date of Month
Gets or sets the day of the month.
// Moment.js
moment().date();
// => 9
moment().date(4);
// => "2018-09-04T09:12:49.695Z"
// Native
new Date().getDate();
// => 9
new Date().setDate(4);
// => "2018-09-04T09:12:49.695Z"
// date-fns
import getDate from 'date-fns/getDate';
import setDate from 'date-fns/setDate';
getDate(new Date());
// => 9
setDate(new Date(), 4);
// => "2018-09-04T09:12:49.695Z"
// dayjs
dayjs().date();
// => 9
dayjs().set('date', 4);
// => "2018-09-04T09:12:49.695Z"
// luxon
DateTime.utc().day;
// => 9
DateTime.utc()
.set({ day: 4 })
.toString();
// => "2018-09-04T09:12:49.695Z"
// Temporal
Temporal.Now.zonedDateTimeISO().day;
// => 9
Temporal.Now.zonedDateTimeISO().with({ day: 4 });
// => "2018-09-04T09:12:49.695Z"
Performance tests
Library | Time |
---|---|
Moment | 1381.669ms |
Native | 397.415ms |
DateFns | 588.004ms |
DayJs | 1218.025ms |
Luxon | 2705.606ms |
Temporal | - |
Day of Week
Gets or sets the day of the week.
// Moment.js
moment().day();
// => 0 (Sunday)
moment().day(-14);
// => "2018-08-26T09:12:49.695Z"
// Native
new Date().getDay();
// => 0 (Sunday)
new Date().setDate(new Date().getDate() - 14);
// => "2018-08-26T09:12:49.695Z"
// date-fns
import getDay from 'date-fns/getDay';
import setDay from 'date-fns/setDay';
getDay(new Date());
// => 0 (Sunday)
setDay(new Date(), -14);
// => "2018-08-26T09:12:49.695Z"
// dayjs
dayjs().day();
// => 0 (Sunday)
dayjs().set('day', -14);
// => "2018-08-26T09:12:49.695Z"
// Luxon
DateTime.local().weekday;
// => 7 (Sunday)
DateTime.local()
.minus({ day: 14 })
.toJSDate();
// => "2018-08-26T09:12:49.695Z"
// Temporal
Temporal.Now.zonedDateTimeISO().dayOfWeek;
// => 7 (Sunday)
Temporal.Now.zonedDateTimeISO().subtract(Temporal.Duration.from({ days: 14 }));
// => "2018-09-04T09:12:49.695Z"
Library | Time |
---|---|
Moment | 1919.404ms |
Native | 543.466ms |
DateFns | 841.436ms |
DayJs | 1229.475ms |
Luxon | 3936.282ms |
Temporal | - |
Day of Year
Gets or sets the day of the year.
// Moment.js
moment().dayOfYear();
// => 252
moment().dayOfYear(256);
// => "2018-09-13T09:12:49.695Z"
// Native
Math.floor(
(new Date() - new Date(new Date().getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24
);
// => 252
// date-fns
import getDayOfYear from 'date-fns/getDayOfYear';
import setDayOfYear from 'date-fns/setDayOfYear';
getDayOfYear(new Date());
// => 252
setDayOfYear(new Date(), 256);
// => "2018-09-13T09:12:49.695Z"
// dayjs â ï¸ requires dayOfYear plugin
import dayOfYear from 'dayjs/plugin/dayOfYear';
dayjs.extend(dayOfYear);
dayjs().dayOfYear();
// => 252
dayjs().dayOfYear(256);
// => "2018-09-13T09:12:49.695Z"
// Luxon
DateTime.local().ordinal;
// => 252
DateTime.local()
.set({ ordinal: 256 })
.toString();
// => "2018-09-13T09:12:49.695Z"
// Temporal
Temporal.Now.zonedDateTimeISO().dayOfYear;
// => 252
Temporal.Now.zonedDateTimeISO().with({month: 1, day: 1}).add(Temporal.Duration.from({days: 256}));
// => "2018-09-04T09:12:49.695Z"
Library | Time |
---|---|
Moment | 5511.172ms |
Native | 530.592ms |
DateFns | 2079.043ms |
DayJs | - |
Luxon | 3540.810ms |
Temporal | - |
Week of Year
Gets or sets the week of the year.
// Moment.js
moment().week();
// => 37
moment().week(24);
// => "2018-06-10T09:12:49.695Z"
// date-fns
import getWeek from 'date-fns/getWeek';
import setWeek from 'date-fns/setWeek';
getWeek(new Date());
// => 37
setWeek(new Date(), 24);
// => "2018-06-10T09:12:49.695Z"
// native getWeek
const day = new Date();
const MILLISECONDS_IN_WEEK = 604800000;
const firstDayOfWeek = 1; // monday as the first day (0 = sunday)
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;
// => 37
// native setWeek
const day = new Date();
const week = 24;
const MILLISECONDS_IN_WEEK = 604800000;
const firstDayOfWeek = 1; // monday as the first day (0 = sunday)
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();
// => "2018-06-10T09:12:49.794Z
// dayjs â ï¸ requires weekOfYear plugin
import weekOfYear from 'dayjs/plugin/weekOfYear';
dayjs.extend(weekOfYear);
dayjs().week();
// => 37
dayjs().week(24);
// => "2018-06-10T09:12:49.695Z"
// Luxon
DateTime.local().weekNumber;
// => 37
DateTime.local()
.set({ weekNumber: 23 })
.toString();
// => "2018-06-10T09:12:49.794Z
// Temporal
Temporal.Now.zonedDateTimeISO().weekOfYear;
// => 252
Temporal.Now.zonedDateTimeISO().with({month: 1, day: 1}).add(Temporal.Duration.from({weeks: 23}));
// => "2018-09-04T09:12:49.695Z"
Library | Time |
---|---|
Moment | 7147.201ms |
Native | 1371.631ms |
DateFns | 5834.815ms |
DayJs | - |
Luxon | 4514.771ms |
Temporal | - |
Days in Month
Get the number of days in the current month.
// Moment.js
moment('2012-02', 'YYYY-MM').daysInMonth();
// => 29
// Native
new Date(2012, 02, 0).getDate();
// => 29
// date-fns
import getDaysInMonth from 'date-fns/getDaysInMonth';
getDaysInMonth(new Date(2012, 1));
// => 29
// dayjs
dayjs('2012-02').daysInMonth();
// => 29
// Luxon
DateTime.local(2012, 2).daysInMonth;
// => 29
// Temporal
(new Temporal.PlainYearMonth(2012, 2)).daysInMonth
// or
Temporal.PlainYearMonth.from('2012-02').daysInMonth
// => 29
Library | Time |
---|---|
Moment | 4415.065ms |
Native | 186.196ms |
DateFns | 634.084ms |
DayJs | 1922.774ms |
Luxon | 1403.032ms |
Temporal | - |
Weeks in Year
Gets the number of weeks in the current year, according to ISO weeks.
// Moment.js
moment().isoWeeksInYear();
// => 52
// Native
const year = new Date().getFullYear();
const MILLISECONDS_IN_WEEK = 604800000;
const firstMondayThisYear = new Date(+year, 0, 5-(new Date(+year, 0, 4).getDay()||7));
const firstMondayNextYear = new Date(+year+1, 0, 5-(new Date(+year+1, 0, 4).getDay()||7));
(firstMondayNextYear - firstMondayThisYear) / MILLISECONDS_IN_WEEK;
// => 52
// date-fns
import getISOWeeksInYear from 'date-fns/getISOWeeksInYear';
getISOWeeksInYear(new Date());
// => 52
// dayjs â ï¸ requires isoWeeksInYear plugin
import isoWeeksInYear from 'dayjs/plugin/isoWeeksInYear';
dayjs.extend(isoWeeksInYear);
dayjs().isoWeeksInYear();
// => 52
// Luxon
DateTime.local().weeksInWeekYear;
// => 52
// Temporal
Temporal.PlainDate.from({day:31, month:12, year: Temporal.Now.plainDateISO()}).weekOfYear
// => 52
Library | Time |
---|---|
Moment | 1065.247ms |
Native | - |
DateFns | 4954.042ms |
DayJs | - |
Luxon | 1134.483ms |
Temporal | - |
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.js
moment.max(array.map(a => moment(a)));
// => "2018-03-11T13:00:00.000Z"
// Native
new Date(Math.max.apply(null, array)).toISOString();
// => "2018-03-11T13:00:00.000Z"
// date-fns
import max from 'date-fns/max';
max(array);
// => "2018-03-11T13:00:00.000Z"
// dayjs â ï¸ requires minMax plugin
import minMax from 'dayjs/plugin/minMax';
dayjs.extend(minMax);
dayjs.max(array.map(a => dayjs(a)));
// => "2018-03-11T13:00:00.000Z"
// Luxon
DateTime.max(...array.map(a => DateTime.fromJSDate(a))).toJSDate();
// => "2018-03-11T13:00:00.000Z"
// Temporal
Temporal.Instant.fromEpochMilliseconds(Math.max.apply(null, array))
// => "2018-03-11T13:00:00.000Z"
Library | Time |
---|---|
Moment | 1780.075ms |
Native | 828.332ms |
DateFns | 980.938ms |
DayJs | - |
Luxon | 2694.702ms |
Temporal | - |
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.js
moment.min(array.map(a => moment(a)));
// => "2016-01-08T13:00:00.000Z"
// Native
new Date(Math.min.apply(null, array)).toISOString();
// => "2016-01-08T13:00:00.000Z"
// date-fns
import min from 'date-fns/min';
min(array);
// => "2016-01-08T13:00:00.000Z"
// dayjs â ï¸ requires minMax plugin
import minMax from 'dayjs/plugin/minMax';
dayjs.extend(minMax);
dayjs.min(array.map(a => dayjs(a)));
// => "2016-01-08T13:00:00.000Z"
// Luxon
DateTime.min(...array.map(a => DateTime.fromJSDate(a))).toJSDate();
// => "2016-01-08T13:00:00.000Z"
// Temporal
Temporal.Instant.fromEpochMilliseconds(Math.min.apply(null, array))
// => "2018-03-11T13:00:00.000Z"
Library | Time |
---|---|
Moment | 1744.459ms |
Native | 819.646ms |
DateFns | 841.249ms |
DayJs | - |
Luxon | 2720.462ms |
Temporal | - |
Manipulate
Add
Add the specified number of days to the given date.
// Moment.js
moment().add(7, 'days');
// => "2018-09-16T09:12:49.695Z"
// Native
const now = new Date();
now.setDate(now.getDate() + 7);
// => "Sun Sep 16 2018 09:12:49"
// date-fns
import addDays from 'date-fns/addDays';
addDays(new Date(), 7);
// => "2018-09-16T09:12:49.695Z"
// dayjs
dayjs().add(7, 'day');
// => "2018-09-16T09:12:49.695Z"
// Luxon
DateTime.local()
.plus({ day: 7 })
.toJSDate();
// => "2018-09-16T09:12:49.695Z"
// Temporal
Temporal.Now.zonedDateTimeISO().add(Temporal.Duration.from({days: 7}));
// => "2018-09-16T09:12:49.695Z"
Library | Time |
---|---|
Moment | 1309.485ms |
Native | 259.932ms |
DateFns | 385.394ms |
DayJs | 1911.881ms |
Luxon | 3919.797ms |
Temporal | - |
Subtract
Subtract the specified number of days from the given date.
// Moment.js
moment().subtract(7, 'days');
// => "2018-09-02T09:12:49.695Z"
// Native
const now = new Date();
now.setDate(now.getDate() - 7);
// => Sun Sep 09 2018 09:12:49
// date-fns
import subDays from 'date-fns/subDays';
subDays(new Date(), 7);
// => "2018-09-02T09:12:49.695Z"
// dayjs
dayjs().subtract(7, 'day');
// => "2018-09-02T09:12:49.695Z"
// Luxon
DateTime.local()
.minus({ day: 7 })
.toJSDate();
// => "2018-09-02T09:12:49.695Z"
// Temporal
Temporal.Now.zonedDateTimeISO().subtract(Temporal.Duration.from({days: 7}));
// => "2018-09-02T09:12:49.695Z"
Library | Time |
---|---|
Moment | 1278.384ms |
Native | 215.255ms |
DateFns | 379.057ms |
DayJs | 1772.593ms |
Luxon | 4028.866ms |
Temporal | - |
Start of Time
Return the start of a unit of time for the given date.
// Moment.js
moment().startOf('month');
// => "2018-08-31T14:00:00.000Z"
// date-fns
import startOfMonth from 'date-fns/startOfMonth';
startOfMonth(new Date());
// => "2018-08-31T14:00:00.000Z"
// dayjs
dayjs().startOf('month');
// => "2018-08-31T14:00:00.000Z"
// Luxon
DateTime.local().startOf('month');
// => "2018-09-02T09:12:49.695Z"
// Temporal
Temporal.Now.zonedDateTimeISO().with({day: 1});
// => "2018-09-01T14:00:00.000Z"
Library | Time |
---|---|
Moment | 1078.948ms |
Native | - |
DateFns | 398.107ms |
DayJs | 765.358ms |
Luxon | 2306.765ms |
Temporal | - |
End of Time
Return the end of a unit of time for the given date.
// Moment.js
moment().endOf('day');
// => "2018-09-09T13:59:59.999Z"
// Native
const end = new Date();
end.setHours(23, 59, 59, 999);
end.toISOString();
// => "2018-09-09T16:59:59.999Z"
// date-fns
import endOfDay from 'date-fns/endOfDay';
endOfDay(new Date());
// => "2018-09-09T13:59:59.999Z"
// dayjs
dayjs().endOf('day');
// => "2018-09-09T13:59:59.999Z"
// Luxon
DateTime.local().endOf('day');
// => "2018-09-02T09:12:49.695Z"
// Temporal
Temporal.Now.zonedDateTimeISO().withPlainTime(new Temporal.PlainTime(23,59,59,999,999,999));
// => "2018-09-09T16:59:59.999999999Z"
Library | Time |
---|---|
Moment | 1241.304ms |
Native | 225.519ms |
DateFns | 319.773ms |
DayJs | 914.425ms |
Luxon | 9920.529ms |
Temporal | - |
Display
Format
Return the formatted date string in the given format.
// Moment.js
moment().format('dddd, MMMM Do YYYY, h:mm:ss A');
// => "Sunday, September 9th 2018, 7:12:49 PM"
moment().format('ddd, hA');
// => "Sun, 7PM"
// Native
new Intl.DateTimeFormat('en-US', { dateStyle: 'full', timeStyle: 'medium' }).format(new Date())
// => "Sunday, September 9, 2018 at 7:12:49 PM"
new Intl.DateTimeFormat('en-US', { weekday: 'short', hour: 'numeric' }).format(new Date())
// => "Sun, 7 PM"
// date-fns
import { intlFormat } from 'date-fns'
intlFormat(new Date(), { dateStyle: 'full', timeStyle: 'medium' }, { locale: 'en-US', })
// => "Sunday, September 9, 2018 at 7:12:49 PM"
intlFormat(new Date(), { weekday: 'short', hour: 'numeric' }, { locale: 'en-US', })
// => "Sun, 7 PM"
// dayjs
dayjs().format('dddd, MMMM D YYYY, h:mm:ss A');
// => "Sunday, September 9 2018, 7:12:49 PM"
dayjs().format('ddd, hA');
// => "Sun, 7PM"
// dayjs â ï¸ requires advancedFormat plugin to support more format tokens
import advancedFormat from 'dayjs/plugin/advancedFormat';
dayjs.extend(advancedFormat);
dayjs().format('dddd, MMMM Do YYYY, h:mm:ss A');
// => "Sunday, September 9th 2018, 7:12:49 PM"
// Luxon
DateTime.fromMillis(time).toFormat('EEEE, MMMM dd yyyy, h:mm:ss a');
// => "Sunday, September 9 2018, 7:12:49 PM" â ï¸ not support 9th
DateTime.fromMillis(time).toFormat('EEE, ha');
// => "Sun, 7PM"
// Temporal
new Intl.DateTimeFormat('en-US', { dateStyle: 'full', timeStyle: 'medium' }).format(Temporal.Now.zonedDateTimeISO())
// => "Sunday, September 9, 2018 at 7:12:49 PM"
new Intl.DateTimeFormat('en-US', { weekday: 'short', hour: 'numeric' }).format(Temporal.Now.zonedDateTimeISO())
// => "Sun, 7 PM"
Time from now
Return time from now.
// Moment.js
moment(1536484369695).fromNow();
// => "4 days ago"
// Native
new Intl.RelativeTimeFormat().format(-4, 'day');
// => "4 days ago"
// date-fns
import formatDistance from 'date-fns/formatDistance';
formatDistance(new Date(1536484369695), new Date(), { addSuffix: true });
// => "4 days ago"
// dayjs â ï¸ requires relativeTime plugin
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
dayjs(1536484369695).fromNow();
// => "5 days ago" â ï¸ the rounding method of this plugin is different from moment.js and date-fns, use with care.
// luxon requires Intl.RelativeTimeFormat
DateTime.local(2022, 1, 27).toRelative({ base: this })
// => "in 4 months"
// Temporal
new Intl.RelativeTimeFormat().format(-4, 'day');
// => "4 days ago"
Time from x
Return time from x.
// Moment.js
moment([2007, 0, 27]).to(moment([2007, 0, 29]));
// => "in 2 days"
// date-fns
import formatDistance from 'date-fns/formatDistance';
formatDistance(new Date(2007, 0, 27), new Date(2007, 0, 29));
// => "2 days"
// dayjs â ï¸ requires relativeTime plugin
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
dayjs('2007-01-27').to(dayjs('2007-01-29'));
// => "in 2 days"
// luxon â does not support relative time
// Temporal
Temporal.PlainDate.from('2007-01-27').until('2007-01-29');
// => Temporal.Duration('P2D')
Difference
Get the unit of time between the given dates.
// Moment.js
moment([2007, 0, 27]).diff(moment([2007, 0, 29]));
// => -172800000
moment([2007, 0, 27]).diff(moment([2007, 0, 29]), 'days');
// => -2
// Native
new Date(2007, 0, 27) - new Date(2007, 0, 29);
// => -172800000
Math.ceil(
(new Date(2007, 0, 27) - new Date(2007, 0, 29)) / 1000 / 60 / 60 / 24
);
// => -2
// date-fns
import differenceInMilliseconds from 'date-fns/differenceInMilliseconds';
differenceInMilliseconds(new Date(2007, 0, 27), new Date(2007, 0, 29));
// => -172800000
import differenceInDays from 'date-fns/differenceInDays';
differenceInDays(new Date(2007, 0, 27), new Date(2007, 0, 29));
// => -2
// dayjs
dayjs('2007-01-27').diff(dayjs('2007-01-29'), 'milliseconds');
// => -172800000
dayjs('2007-01-27').diff(dayjs('2007-01-29'), 'days');
// => -2
// luxon
DateTime.local(2007, 1, 27).diff(DateTime.local(2007, 1, 29)).milliseconds;
// => -172800000
DateTime.local(2007, 1, 27).diff(DateTime.local(2007, 1, 29), 'days').days;
// => -2
// Temporal
Temporal.PlainDate.from('2007-01-27').since('2007-01-29').total({unit: 'millisecond'});
// => -172800000
Temporal.PlainDate.from('2007-01-27').since('2007-01-29').total({unit: 'day'});
// => -2
Query
Is Before
Check if a date is before another date.
// Moment.js
moment('2010-10-20').isBefore('2010-10-21');
// => true
// Native
new Date(2010, 10, 20) < new Date(2010, 10, 21);
// => true
// date-fns
import isBefore from 'date-fns/isBefore';
isBefore(new Date(2010, 9, 20), new Date(2010, 9, 21));
// => true
// dayjs
dayjs('2010-10-20').isBefore('2010-10-21');
// => true
// luxon
DateTime.fromISO('2010-10-20') < DateTime.fromISO('2010-10-21');
// => true
// Temporal
Temporal.PlainDate.compare('2010-10-20', '2010-10-21') === -1;
// => true
Is Same
Check if a date is the same as another date.
// Moment.js
moment('2010-10-20').isSame('2010-10-21');
// => false
moment('2010-10-20').isSame('2010-10-20');
// => true
moment('2010-10-20').isSame('2010-10-21', 'month');
// => true
// Native
new Date(2010, 9, 20).valueOf() === new Date(2010, 9, 21).valueOf();
// => false
new Date(2010, 9, 20).valueOf() === new Date(2010, 9, 20).valueOf();
// => true
new Date(2010, 9, 20).getTime() === new Date(2010, 9, 20).getTime();
// => true
new Date(2010, 9, 20).valueOf() === new Date(2010, 9, 20).getTime();
// => true
new Date(2010, 9, 20).toDateString().substring(4, 7) ===
new Date(2010, 9, 21).toDateString().substring(4, 7);
// => true
// date-fns
import isSameDay from 'date-fns/isSameDay';
import isSameMonth from 'date-fns/isSameMonth';
isSameDay(new Date(2010, 9, 20), new Date(2010, 9, 21));
// => false
isSameDay(new Date(2010, 9, 20), new Date(2010, 9, 20));
// => true
isSameMonth(new Date(2010, 9, 20), new Date(2010, 9, 21));
// => true
// dayjs
dayjs('2010-10-20').isSame('2010-10-21');
// => false
dayjs('2010-10-20').isSame('2010-10-20');
// => true
dayjs('2010-10-20').isSame('2010-10-21', 'month');
// => true
// luxon
(+DateTime.fromISO('2010-10-20') ===
+DateTime.fromISO('2010-10-21') +
// => false
DateTime.fromISO('2010-10-20')) ===
+DateTime.fromISO('2010-10-20');
// => true
DateTime.fromISO('2010-10-20').hasSame(DateTime.fromISO('2010-10-21'), 'month');
// => true
// Temporal
Temporal.PlainDate.from('2010-10-20').equals('2010-10-21');
// => false
Temporal.PlainDate.from('2010-10-20').equals('2010-10-20');
// => true
Temporal.PlainDate.from('2010-10-20').month === Temporal.PlainDate.from('2010-10-21').month;
// => true
Is After
Check if a date is after another date.
// Moment.js
moment('2010-10-20').isAfter('2010-10-19');
// => true
// Native
new Date(2010, 9, 20) > new Date(2010, 9, 19);
// => true
// date-fns
import isAfter from 'date-fns/isAfter';
isAfter(new Date(2010, 9, 20), new Date(2010, 9, 19));
// => true
// dayjs
dayjs('2010-10-20').isAfter('2010-10-19');
// => true
// luxon
DateTime.fromISO('2010-10-20') > DateTime.fromISO('2010-10-19');
// => true
// Temporal
Temporal.PlainDate.compare('2010-10-20', '2010-10-19') === 1;
// => true
Is Between
Check if a date is between two other dates.
// Moment.js
moment('2010-10-20').isBetween('2010-10-19', '2010-10-25');
// => true
// date-fns
import isWithinInterval from 'date-fns/isWithinInterval';
isWithinInterval(new Date(2010, 9, 20), {
start: new Date(2010, 9, 19),
end: new Date(2010, 9, 25),
});
// => true
// dayjs â ï¸ requires isBetween plugin
import isBetween from 'dayjs/plugin/isBetween';
dayjs.extend(isBetween);
dayjs('2010-10-20').isBetween('2010-10-19', '2010-10-25');
// => true
// luxon
Interval.fromDateTimes(
DateTime.fromISO('2010-10-19'),
DateTime.fromISO('2010-10-25')
).contains(DateTime.fromISO('2010-10-20'));
// => true
Is Leap Year
Check if a year is a leap year.
// Moment.js
moment([2000]).isLeapYear();
// => true
// Native
new Date(2000, 1, 29).getDate() === 29;
// => true
// date-fns
import isLeapYear from 'date-fns/isLeapYear';
isLeapYear(new Date(2000, 0, 1));
// => true
// dayjs â ï¸ requires isLeapYear plugin
import isLeapYear from 'dayjs/plugin/isLeapYear';
dayjs.extend(isLeapYear);
dayjs('2000-01-01').isLeapYear();
// => true
// luxon
expect(DateTime.local(2000).isInLeapYear).toBeTruthy();
// => true
// Temporal
Temporal.PlainDate.from('2000-01-01').inLeapYear;
// => true
Is a Date
Check if a variable is a native js Date object.
// Moment.js
moment.isDate(new Date());
// => true
// Native
new Date() instanceof Date;
// => true
// date-fns
import isDate from 'date-fns/isDate';
isDate(new Date());
// => true
// dayjs
dayjs(new Date()).isValid();
// luxon
DateTime.local().isValid;
// => true
// Temporal
new Date() instanceof Date;
Temporal.Now.plainTimeISO() instanceof Temporal.PlainTime;
Temporal.Now.plainDateISO() instanceof Temporal.PlainDate;
Temporal.Now.plainDateTimeISO() instanceof Temporal.PlainDateTime;
Temporal.Now.zonedDateTimeISO() instanceof Temporal.ZonedDateTime;
// => true
License
MIT
Top Related Projects
⏳ Modern JavaScript date utility library ⌛️
⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API
A tiny (349B) reusable date formatter. Extremely fast!
⏱ A library for working with dates and times in JS
Tiny millisecond conversion utility
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot