Format Dates Using Vanilla JavaScript

May 3, 2019

There are numerous libraries, like moment, that allow you to format dates in JavaScript. However, you don't need them for basic date formatting: the built-in Date#toLocaleString() function lets you convert dates into custom string formats with no outside libraries.

Introducing toLocaleString()

The toLocaleString() function takes 2 arguments:

1) A string locale that represents the high level format of the date, like 'en-US' or 'default'.

2) An object options that contains how to format various date components, like month or minutes.

Here's an example of formatting a date to include the short form of the weekday and the full date.

// No 'Z' at the end means JavaScript will use the server's timezone
// as opposed to UTC.
const date = new Date('2019-06-01T00:00:00.000');

// "Sat, June 01, 2019"
date.toLocaleString('en-US', {
  weekday: 'short', // "Sat"
  month: 'long', // "June"
  day: '2-digit', // "01"
  year: 'numeric' // "2019"
});

Note: Don't confuse toLocaleString() with toLocaleDateString(). The toLocaleDateString() function is similar to toLocaleString(), except for it doesn't include the time portion of the date by default.

const date = new Date('2019-06-01T08:00:00.000');

// "6/1/2019, 8:00:00 AM"
date.toLocaleString('en-US');
// "6/1/2019" with no time portion
date.toLocaleDateString();

// But you can still include `hours` and `minutes` using options
// with `toLocaleDateString()`.
date.toLocaleDateString('en-US', {
  month: 'long',
  day: '2-digit',
  year: 'numeric',
  hour: '2-digit'
}); // "June 01, 2019, 8 AM"

Timezones

The toLocaleString() function also lets you specify a timezone to format the date in. Which timezones are supported is implementation-specific, so you shouldn't rely on named timezones like 'America/Los_Angeles' or 'America/New_York' without testing your environment first. For example, Node.js pulls timezone data from your OS, so that means your Node process most likely has timezone data, but that is not strictly guaranteed.

Below is an example of formatting a UTC date with a specific timezone, 'America/Denver'.

const date = new Date('2019-06-01T08:00:00.000Z');
// "June 01, 2019, 2 AM"
date.toLocaleDateString('en-US', {
  month: 'long',
  day: '2-digit',
  year: 'numeric',
  hour: '2-digit',
  timeZone: 'America/Denver' // 6 hours behind UTC
});

Limitations

The toLocaleString() function is good enough for simple human-readable formatting, but it doesn't have the same level of control that you have with moment.

For example, toLocaleString() doesn't have a way to output a date in YYYYMMDD format, such as '20190601' for June 1, 2019. You can output a date in YYYY-MM-DD, but you have to guess a compatible locale. There's no way to output YYYY-MM-DD using the 'en-US' locale, but you can do it with the 'fr-CA' locale.

const date = new Date('2019-06-01T00:00:00.000');
// "June 01, 2019, 2 AM"
date.toLocaleDateString('fr-CA', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit'
});

Unfortunately, figuring out the right locale requires trial and error. If you need more powerful formatting than just 'June 1, 2019', you're better off using moment.


More Fundamentals Tutorials