JavaScript Date and moment.js

Published: January 04, 2017  •  Updated: October 25, 2017  •  javascript

JavaScript provides the global object Date to handle date and time in a JavaScript application. Calling the constructor function without any arguments returns an object that represents the current date and time.

const now = new Date();

Don’t forget the new keyword. Calling Date() without new returns a string.

const nowStr = Date(); // "Wed Jan 04 2017 06:15:26 GMT+0100 (W. Europe Standard Time)"

Calling the constructor with arguments creates a Date object for a specific time. The argument may be a string in the RFC2822 or in a variant of the ISO 8601 standard format.

const d = new Date("2017-01-04T08:05:10"); // Wed Jan 04 2017 09:05:10 GMT+0100 (W. Europe Standard Time)

The Date object provides a parse(string) function which calls new Date(string).

Instead of a string the constructor accepts a number that represents the milliseconds since midnight 1970/1/1.

const d = new Date(1483508319399);  // Wed Jan 04 2017 06:38:39 GMT+0100 (W. Europe Standard Time)

As a third option the constructor can be called with numbers for year, month, day of month, hour, minutes, seconds and milliseconds. The time units are optional and if omitted will be set to 0.

const d1 = new Date(2017, 0, 4); // Wed Jan 04 2017 00:00:00 GMT+0100
const d2 = new Date(2017, 11, 7, 13, 5, 10, 0); // Thu Dec 07 2017 13:05:10 GMT+0100

Note that the month is 0 based! (0 = January, 11 = December).

The Date object contains several functions that return a unit of the given date.

const year = d2.getFullYear(); // 2017
const month = d2.getMonth(); // 11
const dayOfMonth = d2.getDate(); // 7
const hours = d2.getHours(); // 13
const minutes = d2.getMinutes(); // 5
const seconds = d2.getSeconds(); // 10
const millis = d2.getMilliseconds(); // 0

There is also a getDay() function, which should not be confused with the getDate() function. getDate() returns the day of the month (1 - 31) and getDay() returns the day of the week for the given date (0 = Sunday, 6 = Saturday)

The above mentioned get functions have a corresponding set function (except getDay). A Date object is mutable and calling a set function will change the given object. This example changes the year to 2018, but keeps the month and day of month.

const nextYear = new Date(2017, 0, 4);
nextYear.setFullYear(2018);  // Thu Jan 04 2018 00:00:00 GMT+0100 (W. Europe Standard Time)

It is possible to do calculation with dates. For example to find out the number of days between two dates a program may utilise the getTime() function that returns the number of milliseconds since 1970/1/1.

const a1 = new Date(2017, 0, 1);
const a2 = new Date(2018, 0, 1);
const diffInMillis = a2.getTime() - a1.getTime();
const diffInDays = diffInMillis / (1000*60*60*24);  // 365

moment.js

As seen in the examples above the Date object does not provide a lot of support for date calculation. There is no support for parsing date strings that are not in one of the supported standard formats. Another area where the built-in Date object lacks support is formating a date to a string.

Fortunately there are many JavaScript libraries out there that fill these gaps. One of the more popular library is moment.js. It's an open source library that is released under the MIT license and hosted on GitHub: https://github.com/moment/moment/

There are many ways to install the library. In a npm application you only have to call install.

npm install moment

Since version 2.13.0 the library contains a Typescript definition file. In a Typescript application one import statement suffices.

import * as moment from 'moment';

An application has access to all the moment.js functionality through the moment object. Calling the moment() function returns an object that encapsulates the current date and time.

const now = moment(); // Moment {_isAMomentObject: true, _isUTC: false, _pf: Object, …}

This is a moment.js specific object, not a JavaScript Date object, but it can be easily converted with the toDate() function.

const aJsDate = now.toDate();

The reverse way is supported too.

const aMoment = moment(aJsDate);

This does clone the date object. Changing the date object does not affect the moment object.

Creating a moment object with a specific date and time is possible by calling the moment() function with arguments.

Like the JavaScript Date a moment object can be created from the number of milliseconds since 1970/1/1.

const m = moment(1483508319399); // Wed Jan 04 2017 06:38:39 GMT+0100

Another possibility is by using an array [year, month, day, hour, minute, second, milliseconds]. Values can be left out from right to left. Every component that is not specified will fall back to the lowest possible value.

const jan1 = moment([2017]); // Sun Jan 01 2017 00:00:00 GMT+0100

Creating a date like this will use the current timezone. To create a date in the UTC timezone an application has to call the utc(...) function.

const jan2 = moment.utc([2017, 0, 2]); // Mon Jan 02 2017 00:00:00 GMT+0000

Note that the month is 0-based.

Another possibility to create a moment object is providing an object as argument. This allows a more readable style.

const jan3 = moment({ month: 0, day: 3, hour:15, minute:10 }); // Tue Jan 03 2017 15:10:00 GMT+0100

Omitted date fields will be set to the current year, month and day of month. Time fields (hour, minute, seconds, milliseconds) will be set to 0.

moment.js supports different names of the date/time units. The following three examples produce the same object.

const m1 = moment({ y: 2017, M: 0, d: 4, h: 15, m: 10, s: 3, ms: 123}); 
const m2 = moment({ year:2017, month: 0, day: 4, hour: 15, minute: 10, second: 3, millisecond: 123});
const m3 = moment({ years:2017,months: 0,days: 4,hours: 15,minutes: 10,seconds: 3,milliseconds: 123});
// Wed Jan 04 2017 15:10:03 GMT+0100

Another way to create a moment object is from strings. The string has to be formatted in the ISO 8601 format.

const endOfYear1 = moment("2017-12-31"); // Sun Dec 31 2017 00:00:00 GMT+0100
const endOfYear2 = moment("2017-12-31 10:30:26.555"); // Sun Dec 31 2017 10:30:26 GMT+0100

If the given string is not provided in a proper ISO 8601 format a string can be provided as the second argument that specifies the format.

const endOfYear3 = moment("31.12.2017", "DD.MM.YYYY"); // Sun Dec 31 2017 00:00:00 GMT+0100

See the documentation of all the supported format tokens.

Calling moment with an invalid date string throws an error.

const start = moment("2017-0-1"); // Error

A moment object can be verified if it contains a valid date and time with the isValid() function.

moment([2017, 13, 20]).isValid(); // false
moment([2017, 11, 11]).isValid(); // true

moment.js provides many set and get functions to change and retrieve parts of a date. Note that the moment object is mutable, setting a value changes the current object.

const dec = moment([2017, 11, 11, 9, 45]); // Mon Dec 11 2017 09:45:00 GMT+0100
dec.hour(10); // Mon Dec 11 2017 10:45:00 GMT+0100
const hour = dec.hour(); // 10

Setters are chainable.

const nextYear = moment().year(2018).month(1).date(23); // Fri Feb 23 2018 07:18:37 GMT+0100

Moment.js provides many additional get and set functions that the built-in Date does not have. For example an application can access the quarter and the week number for a certain date.

const quarter = moment("2017-06-03").quarter(); // 2
const quarter2 = moment("2017-06-03").quarter(3); // Sun Sep 03 2017 00:00:00 GMT+0200

const week = moment("2017-03-06").week(); // 10
const week2 = moment("2017-03-06").week(11); // Mon Mar 13 2017 00:00:00 GMT+0100

See the documentation for a list of all get and set functions.

Another way to manipulate moment objects is by adding or subtracting a unit of time.

const b = moment([2017,0,1]).add(7, 'days'); // Sun Jan 08 2017 00:00:00 GMT+0100
const c = moment([2017,0,1]).subtract(1, 'years'); // Fri Jan 01 2016 00:00:00 GMT+0100

See the documentation for a list of the supported unit names.

Like the setter functions these functions may be chained.

const d = moment([2017,0,1]).add(10, 'weeks').subtract(2, 'days'); // Fri Mar 10 2017 00:00:00 GMT+0100

An alternative form is to provide an object literal.

const e = moment([2017,0,1,10,5,0]).add({hours: 2, minutes: 10, seconds: 20}); 
// Sun Jan 01 2017 12:15:20 GMT+0100

With the functions startOf and endOf a moment object can be set to the first or last point of a specific time unit. For example to get the first and last day of a month.

const firstDay = moment([2017,1,12]).startOf('month'); // Wed Feb 01 2017 00:00:00 GMT+0100
const lastDay = moment([2017,1,12]).endOf('month'); // Tue Feb 28 2017 23:59:59 GMT+0100

Comparing dates is also a part that is covered by moment.js. Different comparisons are possible to check if a date is the same or before or after another date. Or if a date is between two other dates.

moment('2017-05-13').isBefore('2017-10-21'); // true
moment('2017-05-13').isAfter('2017-10-21'); // false
moment('2017-05-13').isSame([2017,4,13]); // true
moment('2017-05-13').isBetween('2017-05-01', '2017-05-015'); // true

Another important part of an application is to show dates to the user. moment.js provides many ways for converting a moment object to a string with the format() function.

const f1 = moment("2017-05-13T10:05:33.987").format(); // "2017-05-13T10:05:33+02:00"
const f2 = moment("2017-05-13T10:05:33.987").format("dddd, MMMM Do YYYY, h:mm:ss a"); 
// "Saturday, May 13th 2017, 10:05:33 am"

const f3 = moment("2017-05-13T10:05:33.987").format("Qo [quarter] YYYY"); // "2nd quarter 2017"

See the documentation for all the supported tokens.

The fromNow() function returns the difference from today to the given date in a human readable string.

const ago = moment([2013, 0, 29]).fromNow(); // "4 years ago"

toNow() is the opposite, which returns the difference between the given date and today.

const i = moment([2013, 0, 29]).toNow(); // "in 4 years"

Another useful function is diff() that returns a number representing the difference between two moment objects.

const w = moment([2017, 1, 1, 15, 10, 10, 90]);
const x = moment([2017, 1, 1, 15, 10, 10, 140]);
const diffInMillis = x.diff(w); // 50

const y = moment([2017, 8, 28]);
const z = moment([2017, 8, 29]);
const diffInDays = z.diff(y, 'days') // 1

moment.js is able to handle not only fixed points in time but also lengths of time. moment.js calls these objects Duration. A duration can be created with the duration() function.

const d1 = moment.duration(100); // PT0.1S  100 milliseconds
const d2 = moment.duration(2, 'weeks'); // P14D
const d3 = moment.duration(2, 'months'); // P2M

An alternative form is calling the function with an object literal.

const d4 = moment.duration({ seconds:7, minutes:7, hours:7, days:7, weeks:7, months:7, years:7 }); 
// P7Y7M56DT7H7M7S

It's also possible to create a Duration object from a ISO 8601 string.

const d5 = moment.duration('P1Y2M3DT4H5M6S');

The humanize() function returns a human readable string of a duration.

const ds1 = moment.duration(1, 'minutes').humanize(); // "a minute"
const ds2 = moment.duration(2, 'minutes').humanize(); // "2 minutes"
const ds3 = moment.duration(24, 'hours').humanize(); // "a day"

A duration object provides getter methods that return a given unit of a duration. The as... functions return the length of the specified unit.

// returns the minute part of the duration
const m = moment.duration(150, 'seconds').minutes(); // 2 

// returns the length of the duration in minutes
const ml = moment.duration(150, 'seconds').asMinutes(); // 2.5

add() and subtract() allows an application to add and subtract a specific unit of time. Like moment objects duration objects are mutable.

const da = moment.duration(3, 'd');
const db = moment.duration(2, 'd');
da.subtract(db); // da = 1 day
da.add(6, 'days'); // da = 7 days

This post only scratches the surface of moment.js. You find a description of all the provided functionality on the official documentation page: http://momentjs.com/docs/