It is certainly possible to
format dates using vanilla JavaScript,
but most JavaScript developers would consider that masochism. The built-in toLocaleString()
function's options syntax is limited and filled with odd quirks.
Moment is the de facto choice for converting dates to neatly
formatted strings in JavaScript, although some people opt out of using Moment to reduce bundle size.
Formatting Dates
Moment's format()
method is what you
use to convert a Moment object to a
string. For example, here's how you would convert a YYYY-MM-DD string into a more
human-readable format:
const moment = require('moment');
const d = new Date('2019/06/01');
moment(d).format('MMMM d, YYYY'); // June 1, 2019
The format()
function takes in a string and replaces all instances of tokens with the corresponding date value. A token is a
substring like 'YYYY'
or 'd'
that Moment knows to replace with a part of the date, like the year or the
day of the month. Below are some commonly used formatting tokens for dates:
YYYY
: 4-digit year'2019'
YY
: 2-digit year'19'
MMMM
: Full-length month'June'
MMM
: 3 character month'Jun'
MM
: Month of the year, zero-padded'06'
M
: Month of the year'6'
DD
: Day of the month, zero-padded'01'
D
: Day of the month'1'
Do
: Day of the month with numeric ordinal contraction'1st'
Here's some common date formats and how to express them in Moment format strings:
'2019-06-01'
:YYYY-MM-DD
'June 1st, 2019'
:MMMM Do, YYYY
'June \'19'
:MMMM 'YY
'6/1/2019'
:M/D/YYYY
Sometimes you want to add text to the format string that conflicts with a moment
token. For example, if you want a more elaborate date like 'The 1st of June'
,
naively you might try the below format:
// 'T126 1st of June'
m.format('The Do of MMMM');
However, you'll get a surprising output: 'T126 1st of June'
. That's because both
h
and e
are moment tokens. You can escape moment tokens using square brackets []
.
// 'The 1st of June'
m.format('[The] Do [of] MMMM');
For locale-aware formatting, you can use
the L
and LL
tokens to get a locale-specific formatting of the date.
moment.locale(); // 'en'
let m = moment(new Date('2019/06/01'));
m.format('L'); // 06/01/2019
m.format('LL'); // 'June 1, 2019'
// Set the Moment locale to Germany
moment.locale('de');
m = moment(new Date('2019/06/01'));
m.format('L'); // '01.06.2019'
m.format('LL'); // '1. Juni 2019'
Formatting Times
Moment also supports formatting times. The format()
function is very flexible, so
you can display just the date component, just the time component, or a combination
of both. For example, here's how you can display a date's time in 2:04pm
format:
const moment = require('moment');
const m = moment(new Date('2019/06/01 14:04:03'));
m.format('h:mma'); // '2:04pm'
Here's a list of commonly used time format tokens.
HH
: hour of day from 0-24, zero-padded,'14'
H
: hour of day from 0-24,'14'
hh
: hour of day on 12-hour clock, zero-padded,'02'
h
: hour of the day on 12 hour clock,'2'
mm
: minute, zero-padded,'04'
m
: minute,'4'
ss
: second, zero-paddeds
: secondA
:'AM'
or'PM'
a
:'am'
or'pm
'
Here's some common date formats and how to express them in Moment format strings:
'14:04'
:HH:mm
'14:04:03'
:HH:mm:ss
'2:04pm'
:h:mma
'2:04 PM'
:h:mm A
Durations
Moment also has the concept of durations
that let you humanize the
difference between two times into something human-friendly like 'a minute ago'
.
The moment.diff()
function returns a Moment duration object that represents the difference between two moments. For example:
const moment = require('moment');
const m1 = moment(new Date('2019/06/01 2:04:03'));
const m2 = m1.clone().add(59, 'seconds');
const duration = moment.duration(m1.diff(m2));
duration.seconds(); // 59
duration.milliseconds(); // 59000
duration.humanize(); // 'a minute'
duration.humanize(true); // 'in a minute'
moment.duration(m2.diff(m1)).humanize(true); // 'a minute ago'
The humanize()
function takes an optional parameter suffix
that, if set to
true, indicates whether the duration is positive or negative ('in a minute' vs 'a minute ago'). The humanize()
function is locale aware, so you can render durations
in your customer's language:
const moment = require('moment');
// Pretend we're in Germany
moment.locale('de');
const m1 = moment(new Date('2019/06/01 2:04:03'));
const m2 = m1.clone().add(59, 'seconds');
const duration = moment.duration(m1.diff(m2));
// Prints "vor einer Minute"
console.log(duration.humanize(true));
Moving On
Moment is an extremely powerful library with an unbelievable breadth of features.
Time zones, localization, addition and subtraction, durations: Moment makes most
complex date tasks easy. In particular, date formatting is usually the first reason
I pull Moment into a new project. The moment.format()
function is so flexible,
it is hard to imagine writing JavaScript without it.