4 alternatives to moment.js for internationalizing dates
Tags: javascript, momentjs
Published: 2019-10-09 13:36:02

---
title: 4 alternatives to moment.js for internationalizing dates
published: true
tags: javascript,momentjs 
canonical_url: https://blog.logrocket.com/4-alternatives-to-moment-js-for-internationalizing-dates/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/w4rr20z02qbgjbgukj52.png
---
**Written by [Esteban Herrera](https://blog.logrocket.com/author/ehrrera/)**✏️

Date formatting is one of the most important aspects when preparing an application to be used in different languages.

[Moment.js](https://momentjs.com/) is one of the most used JavaScript libraries to format and manipulate dates that we can use for this purpose. However, in some cases, some things [about this library](https://inventi.studio/en/blog/why-you-shouldnt-use-moment-js) (like its size or the way it is structured) might make you wonder if there are some alternatives out there.

In this article, I’m going to review four alternatives to moment.js regarding date internationalization:

- [JavaScript Internationalization API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
- [luxon](https://moment.github.io/luxon/)
- [date-fns](https://date-fns.org/)
- [day.js](https://github.com/iamkun/dayjs)

I’m going to focus on converting dates to strings in different formats for different locales, including relative time.

Let’s start with the JavaScript Internationalization API.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## JavaScript Internationalization API

`Intl` is a global object that acts as the namespace of the ECMAScript Internationalization API. Regarding dates, this object provides the following constructors:

- `Intl.DateTimeFormat`, which provides date and time formatting
- `Intl.RelativeTimeFormat`, which provides language-sensitive easy-to-read phrases for dates and timestamps

These constructors take two optional arguments, the locale and an object with options to customize the output. For example:

```jsx
let rtf = new Intl.RelativeTimeFormat('en-GB', { style: 'long' });
let dtf = new Intl.DateTimeFormat('de');
```

The locale argument is a string that represents a [BCP 47 language tag](https://github.com/libyal/libfwnt/wiki/Language-Code-identifiers), which is composed of the following parts:

- Language code ([ISO 639-1/639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)). For example, `el` (modern greek)
- Script code ([ISO 15924](https://unicode.org/iso15924/iso15924-codes.html)). For example, `Grek` (greek)
- Country code ([ISO 3166](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes)). For example, `GR` (Greece)
- Variant (from [iana.org](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)), search for “Type: variant”). For example, `polyton` (polytonic greek)
- Extensions (from Unicode, more information [here](https://www.w3.org/International/multilingualweb/dublin/slides/23b-davis.pdf)). For example, `u-nu-native` (native digits)

Here’s an example with all the parts together:

```jsx
let rtf = new Intl.RelativeTimeFormat('el-Grek-GR-polyton-u-nu-native');
```

Only the first part (language code) is required, and you can pass an array of strings to define fallback languages:

```jsx
// Requests Dutch as the primary language and if it is not available, it requests french
let dtf = new Intl.DateTimeFormat(['nl', 'fr'])
```

If a locale is not provided, the locale of the runtime environment is used.

About the second argument, the options object, it varies between constructors.

`Intl.DateTimeFormat` takes options such as the style of the date (`full`, `long`, `medium`, and `short`), whether to use either a 12-hour or 24-hour time or format the representation of parts of the day like the year, month, weekday, etc.

In the [documentation page of Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat#Syntax), you can learn more about all the options you can use to customize this object.

About `Intl.RelativeTimeFormat`, the options object only has the following properties:

- `localeMatcher`, the locale matching algorithm to use. The possible values are `lookup` (from the more specific to the less specific, if `en-us` is not available, `en` is chosen) and `best fit` (the default value, if `en-us` is not available, something like `en-uk` can be chosen)
- `numeric`, to format the output message. The possible values are `always` (for example, `2 hours ago`) or `auto`, which doesn’t always allow numeric values in the output (for example, `yesterday`)
- `style`, to format the length of the output message. The possible values are `long`, `short`, and `narrow`

Once you have an object of type `Intl.DateTimeFormat` or `Intl.RelativeTimeFormat`, you can use the methods `format()` or `formatToParts()` (that returns an array with the parts of the output) to format a date.

In the case of `Intl.DateTimeFormat`, the methods take the `Date` object to format:

```jsx
const date = new Date(Date.UTC(2014, 8, 19, 14, 5, 0));
const options = {
   dateStyle: 'short',
   timeStyle: 'full',
   hour12: true,
   day: 'numeric',
   month: 'long',
   year: '2-digit',
   minute: '2-digit',
   second: '2-digit',
};
// Sample output: 19 septembre 14 à 05:00
console.log(new Intl.DateTimeFormat("fr", options).format(date));
// Sample output: 19. September 14, 05:00
console.log(new Intl.DateTimeFormat("de-AT", options).format(date));
/* Sample output: [{"type":"day","value":"19"},{"type":"literal","value":" "},{"type":"month","value":"settembre"},{"type":"literal","value":" "},{"type":"year","value":"14"},{"type":"literal","value":", "},{"type":"minute","value":"05"},{"type":"literal","value":":"},{"type":"second","value":"00"}] */
console.log(new Intl.DateTimeFormat("it", options).formatToParts(date));
```

Notice that if you only specify a few date-time components in the options object, these will be the ones present in the output:

```jsx
const date = new Date(Date.UTC(2014, 08, 19, 14, 5, 0));
const options = {
   year: '2-digit',
};
// Output: 14
console.log(new Intl.DateTimeFormat("en", options).format(date));
```

In the case of `Intl.RelativeTimeFormat`, `format()` takes the numeric value to use in the message and a second argument to indicate the unit of this value (like `year` or `second`, in either singular or plural forms):

```jsx
const options = {
   localeMatcher: 'best fit',
   numeric: 'auto',
   style: 'short',
};
// Output: last mo.
console.log(new Intl.RelativeTimeFormat("en-CA", options).format(-1, 'month'));
// Output: la semana pasada
console.log(new Intl.RelativeTimeFormat("es-ES", options).format(-1, 'week'));
/* Output: [{"type":"integer","value":"60","unit":"minute"},{"type":"literal","value":" 分鐘前"}] */
console.log(new Intl.RelativeTimeFormat("zh-TW", options).formatToParts(-60, 'minutes'));
```

Also, notice the difference between using the `always` and `auto` values for the `numeric` property:

```jsx
// Output: in 0 days
console.log(new Intl.RelativeTimeFormat("en", {numeric: 'always'}).format(0, 'day'));
// Output: today
console.log(new Intl.RelativeTimeFormat("en", {numeric: 'auto'}).format(0, 'day'));
```

You can try and modify all of the above examples [here](https://codesandbox.io/s/intl-datetimeformat-example-e32u4) and [here](https://codesandbox.io/s/intl-relativetimeformat-example-5xy7l), but depending on the browser you’re using, you could get some errors.

Most of the functionality of `Intl.DateTimeFormat` is well-supported in modern browsers (more info [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat#Browser_compatibility)), however, `Intl.RelativeTimeFormat` is fully supported only from Chrome 71 and Firefox 70 (no support in Safari or Edge at the time of this writing).

You can use a [polyfill](https://github.com/catamphetamine/relative-time-format), but you’ll have to create the object differently:

```jsx
const myLocale = /* Import JSON file for the choosen locale */;
const localeTag = /* Tag for the above locale */;
const options = { /* Options object */ };
RelativeTimeFormat.addLocale(myLocale);
new RelativeTimeFormat(localeTag, options).format(3, 'day');
```

You can try this example [here](https://codesandbox.io/s/intl-relativetimeformat-polyfill-example-eq2y9).

So as you can see, `Intl.RelativeTimeFormat` is similar to `moment.duration().humanize()`:

```jsx
moment.duration(-1, 'weeks').humanize(true); // a week ago
```

If you’re used to calculating relative times from now or calendar times relative to a given reference time the way moment.js does:

```jsx
moment('20140919', 'YYYYMMDD').fromNow(); // 5 years ago
moment().add(5, 'days').calendar(); // Tuesday at 1:15 PM
```

You’ll need to manually calculate the [difference between the two dates](https://stackoverflow.com/questions/3224834/get-difference-between-2-dates-in-javascript).

Nothing beats using native features, but if this can become a problem, there are other options.

## Luxon

[Luxon](https://moment.github.io/luxon/index.html) is a library [created by one of moment’s maintainers](https://github.com/moment/luxon/blob/master/docs/why.md), so it borrows many ideas from it while offering improvements in some areas.

For internationalization purposes, you can think of Luxon as a wrapper for `Intl.DateTimeFormat` and `Intl.RelativeTimeFormat`.

For example, one way to format dates according to a locale is by first setting the locale and then using the method `toFormat(fmt:string, opts: Object)` along with date-time tokens from [this table](https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens):

```jsx
// Sample output: 2019 сентябрь
console.log(DateTime.local().setLocale('ru').toFormat('yyyy MMMM'));
```

You can also pass the locale in the options object that the method can take as an argument:

```jsx
// Output: 2019 сентябрь
console.log(DateTime.local(2018, 9, 1).toFormat('yyyy MMMM', { locale: "ru" }));
```

Or if you’re using methods like [fromObject](https://moment.github.io/luxon/docs/class/src/class/src/datetime.js~DateTime.html#static-method-fromObject), [fromISO](https://moment.github.io/luxon/docs/class/src/class/src/datetime.js~DateTime.html#static-method-fromISO), [fromHTTP](https://moment.github.io/luxon/docs/class/src/class/src/datetime.js~DateTime.html#static-method-fromHTTP), [fromFormat](https://moment.github.io/luxon/docs/class/src/class/src/datetime.js~DateTime.html#static-method-fromFormat), or [fromRFC2822](https://moment.github.io/luxon/docs/class/src/class/src/datetime.js~DateTime.html#static-method-fromRFC2822), you can set the locale at creation time:

```jsx
const italianDate = DateTime.fromISO("2014-09-19", { locale: "it" });
// Output: 2014 settembre 19
console.log(italianDate.toFormat("yyyy MMMM dd"));
```

However, the recommended way is to use the methods `toLocaleString()` and `toLocaleParts()` that returns a localized string representing the date and an array with the individual parts of the string, respectively.

These methods are equivalent to the methods `format()` and `formatToParts()` of `Intl.DateTimeFormat`, and in fact, they take the same options object (along with some presets, such as `DateTime.DATE_SHORT`, [among others](https://moment.github.io/luxon/docs/manual/formatting.html#presets)):

```jsx
const date = DateTime.utc(2014, 9, 1, 14, 5, 0);
const options = {
  dateStyle: "short",
  timeStyle: "full",
  hour12: true,
  day: "numeric",
  month: "long",
  year: "2-digit",
  minute: "2-digit",
  second: "2-digit"
};
// Output: 1 septembre 14 à 05:00 
console.log(date.setLocale("fr").toLocaleString(options));
// Output: 1. September 14, 05:00 
console.log(date.setLocale("de-AT").toLocaleString(options));
/* Output: [{"type":"day","value":"1"},{"type":"literal","value":" "},{"type":"month","value":"settembre"},{"type":"literal","value":" "},{"type":"year","value":"14"},{"type":"literal","value":", "},{"type":"minute","value":"05"},{"type":"literal","value":":"},{"type":"second","value":"00"}] */
console.log(
  JSON.stringify(date.setLocale("it").toLocaleParts(options), null, 3)
);
// Output: 2:05 PM
console.log(date.toLocaleString(DateTime.TIME_SIMPLE));
// Output: 01/09/2014 
console.log(date.toLocaleString({ locale: 'pt' }));
```

This means that:

- Luxon can be configured using the same [BCP 47](https://tools.ietf.org/html/rfc5646) locale strings as the `Intl` object
- If the `Intl` object is not available in your target browser, this part of the library won’t work properly (for Node.js applications you might need to take [some extra steps to set up the library](https://moment.github.io/luxon/docs/manual/install.html#node))
- Regarding internationalization, Luxon acts as a wrapper for the JavaScript Internationalization API, but it sets the locale at the level of the `DateTime` Luxon object (more info [here](https://moment.github.io/luxon/docs/manual/intl.html))

On the other hand, the methods [toRelative](https://moment.github.io/luxon/docs/class/src/datetime.js~DateTime.html#instance-method-toRelative) (that returns a string representation of a given time relative to now, by default) and [toRelativeCalendar](https://moment.github.io/luxon/docs/class/src/datetime.js~DateTime.html#instance-method-toRelativeCalendar) (that returns a string representation of a given date relative to today, by default) are the ones that provide functionality similar to `Intl.RelativeTimeFormat`:

```jsx
// Sample output: in 23 hours 
console.log(DateTime.local().plus({ days: 1 }).toRelative());
// Sample output: tomorrow
console.log(DateTime.local().plus({ days: 1 }).toRelativeCalendar());
// Sample output: in 1 Tag 
console.log(DateTime.local().plus({ days: 1 }).toRelative({ locale: "de" }));
// Sample output: morgen 
console.log(DateTime.local().plus({ days: 1 }).toRelativeCalendar({ locale: "de" }));
// Sample output: il y a 1 semaine 
console.log(DateTime.local().setLocale("fr").minus({ days: 9 }).toRelative({ unit: "weeks" }));
// Sample output: la semaine dernière 
console.log(DateTime.local().setLocale("fr").minus({ days: 9 }).toRelativeCalendar({ unit: "weeks" }));
```

Unlike `Intl.RelativeTimeFormat`, if your browser doesn’t support this API, the above methods won’t throw an error, the only problem is that they will not be translated to the appropriate language.

You can try all of the above examples [here](https://codesandbox.io/s/luxon-example-gmi98).

## Date-fns

[Date-fns](https://date-fns.org) is another popular JavaScript library for date processing and formatting. Version 2, the latest at the time of this writing, only comes in the form of an [NPM package](https://date-fns.org/v2.2.1/docs/Getting-Started#installation), so if you want to use it directly in a browser, you’ll have to use a bundler like [Browserify](http://browserify.org).

This library contains around sixty different locales ([here](https://github.com/date-fns/date-fns/tree/master/src/locale) you can see all of them). To use one or more locales, you need to import them like this:

```jsx
import { es, enCA, it, ptBR } from 'date-fns/locale'
```

The functions that accept a locale as argument are the following:

- [format](https://date-fns.org/v2.2.1/docs/format), which returns the formatted date, taking as parameters the date, a string representing the pattern to format the date (based on the date fields symbols of the [Unicode technical standard #35](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)), and an object with options like the locale and the index of the first day of the week
- [formatDistance](https://date-fns.org/v2.2.1/docs/formatDistance), which returns the distance between the given dates in words, taking as parameters the dates to compare and an object with options like the locale or whether to include seconds
- [formatDistanceToNow](https://date-fns.org/v2.2.1/docs/formatDistanceToNow) is the same as `formatDistance` but only takes one date (that will be compared to now)
- [formatDistanceStrict](https://date-fns.org/v2.2.1/docs/formatDistanceStrict) is the same as `formatDistance` but without using helpers like `almost`, `over`, or `less than`. The options object has properties to force a time unit and to specify the way to round partial units
- [formatRelative](https://date-fns.org/v2.2.1/docs/formatRelative), which represents the date in words relative to a given base date. It can also take an options object as an argument, to set the locale and the index of the first day of the week

Here are some examples:

```jsx
import {
   format,
   formatDistance,
   formatDistanceToNow,
   formatDistanceStrict,
   formatRelative,
   addDays
 } from "date-fns";
 import { es, enCA, ro, it, ptBR } from "date-fns/locale";

 // Output: septiembre / 19
 console.log(format(new Date(), "MMMM '/' yy", { locale: es }));
 // Output: in less than 10 seconds
 console.log(
   formatDistance(
     new Date(2019, 8, 1, 0, 0, 15),
     new Date(2019, 8, 1, 0, 0, 10),
     { locale: enCA, includeSeconds: true, addSuffix: true }
   )
 );
 // Output: less than 10 seconds ago
 console.log(
   formatDistance(
     new Date(2019, 8, 1, 0, 0, 10),
     new Date(2019, 8, 1, 0, 0, 15),
     { locale: enCA, includeSeconds: true, addSuffix: true }
   )
 );
 // Output: circa 15 ore (assuming now is 9/20/2019 15:00)
 console.log(formatDistanceToNow(new Date(2019, 8, 20), { locale: ro }));
 // Output: 0 minuti
 console.log(
   formatDistanceStrict(
     new Date(2019, 8, 1, 0, 0, 15),
     new Date(2019, 8, 1, 0, 0, 10),
     { locale: it, unit: "minute" }
   )
 );
 // Output: un minuto
 console.log(
   formatDistanceStrict(
     new Date(2019, 8, 1, 0, 0, 10),
     new Date(2019, 8, 1, 0, 0, 15),
     { locale: it, unit: "minute", roundingMethod: "ceil" }
   )
 );
 // Output: amanhã às 14:48
 console.log(formatRelative(addDays(new Date(), 1), new Date(), { locale: ptBR }));
```

`formatRelative` is usually used with helpers to add or subtract different units of time like [addWeeks](https://date-fns.org/v2.2.1/docs/addWeeks), [subMonths](https://date-fns.org/v2.2.1/docs/subMonths), [addQuarters](https://date-fns.org/v2.2.1/docs/addQuarters), among others.

Also, consider that if the distance between the dates is more than six days, `formatRelative` will return the date given as the first argument:

```jsx
// If today is September 20, 2019 the output will be 27/09/2019
console.log(formatRelative(addDays(new Date(), 7), new Date(), { locale: ptBR }));
```

You can try all of the above examples [here](https://codesandbox.io/s/date-fns-example-pvkpn).

## Day.js

Day.js is a lightweight library with an API similar to moment.js’.

By default, Day.js comes with the United States English locale. To use other locales, you need to import them like this:

```jsx
import 'dayjs/locale/pt';
import localeDe from 'dayjs/locale/de'; // With a custom alias for the locale object

dayjs.locale('pt') // use Portuguese locale globally
// To use the locale just in certain places
console.log(
  dayjs()
    .locale(localeDe)
    .format()
);
console.log( dayjs('2018-4-28', { locale: 'pt' }) );
```

[Here](https://github.com/iamkun/dayjs/tree/dev/src/locale) you can find the list of all supported locales.

In the above example, the [format()](https://github.com/iamkun/dayjs/blob/dev/docs/en/API-reference.md#format-formatstringwithtokens-string) method returns a string with the formatted date. It can take a string with the tokens to format the date in a specific way:

```jsx
// Sample output: September 2019, Samstag
console.log(
  dayjs()
    .locale(localeDe)
    .format('MMMM YYYY, dddd')
);
```

[Here](https://github.com/iamkun/dayjs/blob/dev/docs/en/API-reference.md#list-of-all-available-formats) is the list of all available formats.

However, much of the advanced functionality of Day.js comes from [plugins](https://github.com/iamkun/dayjs/blob/dev/docs/en/Plugin.md) that you can load based on your needs. For example, the [UTC](https://github.com/iamkun/dayjs/blob/dev/docs/en/Plugin.md#utc) plugin adds methods to get a date in UTC and local time:

```jsx
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";

dayjs.extend(utc);

console.log(dayjs.utc().format()); // Sample output: 2019-09-21T11:31:55Z
```

Regarding internationalization, we can use the [AdvancedFormat](https://github.com/iamkun/dayjs/blob/dev/docs/en/Plugin.md#advancedformat), [LocalizedFormat](https://github.com/iamkun/dayjs/blob/dev/docs/en/Plugin.md#localizedformat), [RelativeTime](https://github.com/iamkun/dayjs/blob/dev/docs/en/Plugin.md#relativetime), and [Calendar](https://github.com/iamkun/dayjs/blob/dev/docs/en/Plugin.md#calendar) plugins.

The AdvancedFormat and LocalizedFormat plugins add more formatting options to the `format()` method (you can see all the options in the [plugins documentation page](https://github.com/iamkun/dayjs/blob/dev/docs/en/Plugin.md#advancedformat)):

```jsx
// ...

// Plugins
import advancedFormat from "dayjs/plugin/advancedFormat";
import localizedFormat from "dayjs/plugin/localizedFormat";

// Load plugins
dayjs.extend(advancedFormat);
dayjs.extend(localizedFormat);

// Advanced format options
// If today is 2019/09/21 at 12:00 PM, the output will be 3 21º 12 12 1569087454 1569087454869
console.log(
  dayjs()
    .locale("pt")
    .format("Q Do k kk X x")
);
// Localized format options
// If today is 2019/09/21 at 12:00 PM, the output will be Sábado, 21 de Setembro de 2019 às 12:00 
console.log(
  dayjs()
    .locale("pt")
    .format("LLLL")
);
```

The `RelativeTime` plugin adds methods to format dates to relative time strings:

- `.fromNow(withoutSuffix?: boolean)` returns a string representing the relative time from now
- `.from(compared: Dayjs, withoutSuffix?: boolean)` returns a string representing the relative time from X
- `.toNow(withoutSuffix?: boolean)` returns a string representing the relative time to now
- `.to(compared: Dayjs, withoutSuffix?: boolean)` returns a string representing the relative time to X

Here are some examples:

```jsx
// ...
import relativeTime from "dayjs/plugin/relativeTime";

// Load plugin
dayjs.extend(relativeTime);

// Assuming now is 2019-09-21 at 12:00 PM
// Output: in einem Jahr 
console.log(
  dayjs()
    .locale(localeDe)
    .from(dayjs("2018-09-21"))
);
// Output: einem Jahr 
console.log(
  dayjs()
    .locale(localeDe)
    .from(dayjs("2018-09-21"), true)
);
// Output: vor einem Jahr 
console.log(
  dayjs("2018-09-21")
    .locale(localeDe)
    .fromNow()
);
// Output: vor 2 Jahren 
console.log(
  dayjs("2018-09-21")
    .locale(localeDe)
    .to(dayjs("2016-09-21"))
);
// Output: vor 11 Jahren 
console.log(
  dayjs("2030-09-21")
    .locale(localeDe)
    .toNow()
);
```

The Calendar plugin adds the `.calendar` method to display calendar time (within a distance of seven days). It doesn’t seem to localize the output:

```jsx
// ...
import calendar from "dayjs/plugin/calendar";

// Load plugin
dayjs.extend(calendar);

// Assuming now is 2019-09-21 at 12:00 PM
// Output: Yesterday at 12:00 PM
console.log(
  dayjs()
    .locale('pt')
    .calendar(dayjs("2019-09-22"))
);
```

However, it allows you to manually customize the output labels for the same day, next day, last weekend, and next week and everything else using string literals (wrapped in square brackets) and date-time format tokens:

```jsx
// Assuming now is 2019-09-21 at 12:00 PM
// The output is Hoje às 12:00
console.log(
  dayjs().calendar(dayjs("2019-09-21"), {
    sameDay: "[Hoje às] h:m",
    nextDay: "[Amanhã]",
    nextWeek: "dddd",
    lastDay: "[Ontem]",
    lastWeek: "[Último] dddd",
    sameElse: "DD/MM/YYYY"
  })
);
```

You can try all of the above examples [here](https://codesandbox.io/s/dayjs-example-cgg4f).

## Conclusion

Moment.js is a robust and mature library for date processing, however, it may be overkill for some projects. In this article, I have compared the way four popular libraries handle date formatting in the context of internationalization.

The features provided by the JavaScript Internationalization API may be enough for simple use cases, but if you need a higher-level API (e.g, relative times) and other features such as timezones or helper methods for adding or subtracting units of time, you may want to consider one of the other libraries reviewed in this article.

Finally, here are some links that you might find useful:

- [BCP 47 Validator](https://schneegans.de/lv/)
- [Intl object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
- [Intl.RelativeTimeFormat API Specification](https://github.com/tc39/proposal-intl-relative-time/)
- [You don’t (may not) need moment.js](https://github.com/you-dont-need/You-Dont-Need-Momentjs)
- [The 7 best JavaScript date libraries](https://dev.to/bnevilleoneill/the-7-best-javascript-date-libraries-2pli)

Happy coding!
* * * 
**Editor's note:** Seeing something wrong with this post? You can find the correct version [here](https://blog.logrocket.com/4-alternatives-to-moment-js-for-internationalizing-dates/).

## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *
The post [4 alternatives to moment.js for internationalizing dates](https://blog.logrocket.com/4-alternatives-to-moment-js-for-internationalizing-dates/) appeared first on [LogRocket Blog](https://blog.logrocket.com).