Managing Dates and Times Using Moment.js

Share this article

Managing Dates and Times Using Moment.js

Working with dates and times in JavaScript has always been a bit cumbersome. Native date methods are verbose and the API is often inconsistent. That’s why if you ask a date-related question on StackOverflow, you’ll often hear the reply “Use Moment.js”.

What Is Moment.js?

Moment.js is a Swiss Army knife for working with dates in JavaScript. It allows you to parse, validate, manipulate, and display dates and times using a clean and concise API.

In this article I’ll show you how to get up and running with Moment.js, as well as demonstrate several of its common use cases.

Warning for New Users: Use date-fns Instead

Note that as of September 2020, we are recommending that users looking to implement a date library use date-fns instead.

Moment.js is a fairly heavy library for its function, and the Chrome dev tools now actively recommend against using it as part of Core Web Vitals performance testing. As a result, the project is in maintenance mode and new feature development is no longer on the table according to the Moment.js maintainers.

Learn date-fns: A Lightweight JavaScript Date Library

Getting Started with Moment.js

Moment.js is freely available for download from the project’s home page. Moment.js can be run from the browser as well as from within a Node application. In order to use it with Node, install the module using the following command.

npm install moment

Then, simply require() and use it in your application as shown below.

const moment = require('moment');
const today = moment();
console.log(today.format());

// 2020-01-09T15:45:51+01:00

In order to run Moment.js from the browser, include it using a <script> tag, as shown below. Moment.js creates a global moment object which can be used to access all the date and time parsing and manipulation functionality.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Moment.js</title>
  </head>
  <body>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
    <script>
      // You have a 'moment' global here
      const today = moment();
      console.log(today.format());
    </script>
  </body>
</html>

Date Formatting

In the past, I recall converting date strings into Date objects, grabbing individual pieces of data, and then performing string concatenations. Moment.js has simplified the process of date conversion to any particular format. Date format conversion with Moment is simple, as shown in the following example.

moment().format('YYYY-MM-DD');

Calling moment() gives us the current date and time, while format() converts it to the specified format. This example formats a date as a four-digit year, followed by a hyphen, followed by a two-digit month, another hyphen, and a two-digit day.

See the Pen
Formatting the Date with Moment.js
by SitePoint (@SitePoint)
on CodePen.

Tip: Try experiment with some of the other date formats listed in the project’s documentation.

Date Validation

Another annoying task that Moment.js has greatly simplified is date validation. In order to perform validation, simply pass a date string to the moment object, along with the desired date format, and call the isValid() method. This will return true if the date is valid, and false otherwise.

console.log(moment("2020-01-01", "YYYY-MM-DD").isValid()); // true
console.log(moment("not-a-date", "YYYY-MM-DD").isValid()); // false

Be aware, however, that Moment gives you the possibility to work with partial dates, which might lead to unexpected results.

console.log(
  moment("2019 was a great year because I got married", "YYYY-MM-DD").isValid()
);
// Returns true because 2019 matches YYYY

To avoid this, you can put Moment into strict parsing mode by passing it true as a third argument.

console.log(
  moment("2019 was a great year because I got married", "YYYY-MM-DD", true).isValid()
);
// false

Here’s an example to showcase this functionality.

See the Pen
Checking Date Validity with Moment.js
by SitePoint (@SitePoint)
on CodePen.

There are a number of other helpful flags in the object returned by moment():

  • overflow – This is set when an overflow occurs. An example would be the 13th month or 32nd day.
  • invalidMonth – Set when the month is invalid, like Jannnuaarry.
  • empty – Set when the entered date contains nothing parsable.
  • nullInput – Set when the entered date is null.

You can read more about these and other available flags on the project’s homepage.

Manipulating Dates

There are a number of options for manipulating the moment object. For example, you can add or subtract days, months, years, etc. This is achieved via the add() and subtract() methods. The following example shows how seven days, months, or weeks are added to the current date.

moment().add(7, 'days');    // adds 7 days to current date
moment().add(7, 'months');  // adds 7 months to current date
moment().add(7, 'years');   // adds 7 years to current date

Similarly, the subtract() method is shown below.

moment().subtract(7, 'days');   // subtracts 7 days to current date
moment().subtract(7, 'months'); // subtracts 7 months to current date
moment().subtract(7, 'years');  // subtracts 7 years to current date

Note that each of the above examples will return the moment object. If you want a human-readable date, you’ll need to format it accordingly.

const today = moment();
const nextWeek = today.add(7, 'days');
console.log(nextWeek.format('dddd Do MMMM, YYYY'));

// Thursday 16th January, 2020

Time From Now

Another common task is determining how much time exists between two dates. For calculating time from the current date, Moment.js uses a method named fromNow(). Here’s how to check how much time has elapsed since the beginning of the decade:

moment('2020.01.01', 'YYYY.MM.DD').fromNow();
// 9 days ago

If we pass in true as an argument, we can get the value without the suffix.

moment('2020.01.01', 'YYYY.MM.DD').fromNow(true);
// 9 days

Time From Another Date

The fromNow() method is used to compare time to the current date. This is just a special case of from(), which compares two arbitrary dates. An example that utilizes from() is shown below.

const dateA = moment('01-01-1900', 'DD-MM-YYYY');
const dateB = moment('01-01-2000', 'DD-MM-YYYY');

console.log(dateA.from(dateB));

You can have a play with this method in the following demo.

See the Pen
Time From Another Date with Moment.js
by SitePoint (@SitePoint)
on CodePen.

Calculating the Difference Between Dates

Moment.js offers a way to calculate the difference between two dates. The difference is calculated in milliseconds by default, but can also be returned in days, months, years, etc. To compute the difference, call the diff() method. This method takes a date as its first argument. The unit of time can be specified using the optional second argument. If this is not included, then milliseconds are used. The following example and demo illustrate how diff() is used.

const dateB = moment('2014-11-11');
const dateC = moment('2014-10-11');

console.log('Difference is ', dateB.diff(dateC), 'milliseconds');
console.log('Difference is ', dateB.diff(dateC, 'days'), 'days');
console.log('Difference is ', dateB.diff(dateC, 'months'), 'months');

See the Pen
Calculating the Difference Between Dates with Moment.js
by SitePoint (@SitePoint)
on CodePen.

Date Queries

Moment.js also provides various date comparison methods. These methods include isBefore(), isAfter(), and isSame() which, as the names imply, return a Boolean indicating if one date is before, after, or equal to another date. An example that uses isAfter() is shown below.

console.log(moment('2020-01-01').isAfter('2019-01-01')); // true
console.log(moment('2020-01-01').isAfter('2020-01-08')); // false

There is also an isLeapYear() method that checks for leap years.

console.log(moment([2020]).isLeapYear()); // true
console.log(moment([2019]).isLeapYear()); // false

International Language Support

Moment.js offers great i18n support. It allows you to assign a global language or set the language for a particular moment object. By default, it supports the English language. If you want to support any other language, then assign the key values of that particular language to moment.locale. The following abridged example, taken from the Moment.js docs, shows how support can be added for French.

const moment = require('moment');

moment.locale('fr', {
  months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),
  weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
  relativeTime : {
      future : 'dans %s',
      past : 'il y a %s',
      s : 'quelques secondes',
      m : 'une minute',
      mm : '%d minutes',
      h : 'une heure',
      hh : '%d heures',
      d : 'un jour',
      dd : '%d jours',
      M : 'un mois',
      MM : '%d mois',
      y : 'un an',
      yy : '%d ans'
  }
});

moment.locale('fr');

console.log(moment(1316116057189).fromNow());
// il y a une heure

console.log(moment().format('dddd Do MMMM, YYYY'));
// jeudi 9e janvier, 2020

See the Pen
Internationalization with Moment.js
by SitePoint (@SitePoint)
on CodePen.

Why Moment Might Not Be a Good Fit

Although Moment.js is an excellent time and date library, it is also something of a behemoth. For example, if you use it with webpack, just an innocent require('moment'); is enough ensure that all of the locales come along for the ride. This significantly increases your bundle size and you need to resort to plugins to get it back down.

It also comes with a great many features, but in contrast to libraries like Lodash, it doesn’t allow you to cherry-pick the ones you need. Rather, you always have to load the entire library.

Another common complaint is that the moment object is mutable. This can leads to confusion among developers. Consider:

const moment = require('moment');
const today = moment();
const nextWeek = today.add(7, 'days');
console.log(today.fromNow());

What would you expect to be logged to the console? Unfortunately, the answer is “in 7 days” (and not “a few seconds ago”), because the code today.add(7, 'days') mutated the moment object, setting it to seven days in the future.

This can be avoided by cloning the moment object before preforming any date math, but by the time you remember to do that, the chances are you’ve already spent quite some time debugging.

const moment = require('moment');
const today = moment();
const nextWeek = today.clone().add(7, 'days');
console.log(today.fromNow());
// a few seconds ago

A Light-weight Alternative

For those of you looking for a lighter alternative, consider date-fns. Date-fns is immutable, always returning a new date instead of changing the one you pass in. It has a simple API, is the perfect companion for Webpack and with its function-per-file style you can pick just what you need.

If you’d like to find out more, read: Introduction to date-fns – a Lightweight JavaScript Date Library

Conclusion

Moment.js is really an awesome library that simplifies date and time-related manipulations and validations. In this article, we focused on some of the features of Moment.js which help in parsing, validating, and manipulating dates and times in the browser and Node.js applications. A number of useful plugins are also available for Moment.js. Plugins like ISO Calendar, Jalaali Calendar, and many more can be found on the official plugin page. For more on Moment.js, the reader is directed to the library’s documentation.

 

FAQs About Moment.js

How to use Moment.js?

Moment.js, a JavaScript library for working with dates and times, can be utilized in your project by installing it through npm or including it from the Moment.js website. You can then import it into your code using CommonJS or ES6 module syntax.
With Moment.js, you can parse dates by providing a date string and a format string, format dates using predefined tokens or custom formats, manipulate dates by adding or subtracting time, and display relative time (e.g., “2 hours ago”).
Additionally, Moment.js supports localization for displaying dates in different languages and formats and offers functionality for handling time zones and conversions.
However, please note that Moment.js is no longer actively maintained as of September 2020, and it’s recommended to consider using modern date and time libraries like date-fns or the native JavaScript Date object with the Intl.DateTimeFormat API for new projects, as they offer better performance and active development.

What is the ISO time format for Moment?

In Moment.js, you can format a date and time in ISO 8601 format using the toISOString() method. The ISO 8601 format represents date and time information in a standardized way.

How do you convert a Moment object to Date object?

To convert a Moment.js object to a JavaScript Date object, you can use the .toDate() method provided by Moment.js. The .toDate() method will return a JavaScript Date object that represents the same date and time as the original Moment.js object. This conversion can be useful when you need to work with standard JavaScript Date objects or when using libraries or APIs that expect Date objects as input.

How do you get the current date in Moment?

To get the current date and time using Moment.js, you can simply call the moment() function without passing any arguments.

How do you increment a date with Moment?

To increment a date using Moment.js, you can use the add() method. The add() method allows you to add or subtract time units (such as days, months, years, etc.) to a Moment.js object.

Jay is a Software Engineer and Writer. He blogs occasionally at Code Handbook and Tech Illumination.

James HibbardJames Hibbard
View Author

Network admin, freelance web developer and editor at SitePoint.

moment.jsNode-JS-Tools
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week