moment vs date-fns locale date formats

Viewed 19788

I'm evaluating DateFns and Moment in the context of our app, and found what appears to be an important omission in DateFns.

In Moment, locale support allows you to format locale-correct representations of a date or time. For instance, the date formats "LL" and "L" will produce the following for the English locale:

November 27, 2017
11/27/2017

And the following for the Spanish locale:

27 de noviembre de 2017
27/11/2017

Note in particular that in the second example, the month comes before the day in English, whereas the day comes before the month in Spanish. That's exactly the kind of thing you want locale code to handle for you. This is how locales work in almost all datetime libraries (C++, C#, Java, Python, etc.)

In the DateFns, there doesn't appear to be a format option for locale-correct long date, short date, time, etc.. The example they give for using a locale requires that you pass it the locale-specific format string:

// Represent 2 July 2014 in Esperanto:
var eoLocale = require('date-fns/locale/eo')
var result = format(
  new Date(2014, 6, 2),
  'Do [de] MMMM YYYY',
  {locale: eoLocale}
)

In other words, I need to know the date/time format for every locale I support, which defeats the purpose of having locale support in the first place.]

I can use Javascript's toLocaleString, but then my app it managing locale two different ways.

Is there some way of printing out, say, a "short date" for a particular locale without me telling DateFns what the format for that locale is?

2 Answers

I use the esm version of date-fns and you can use the same type of formats that moment uses :

import { format } from 'date-fns/esm'
import { enUS, fr } from 'date-fns/esm/locale'

I'll store the locales in an object :

this.dateLocales = { fr: fr, en: enUS }

and use these formats :

LT: 'h:mm aa',
LTS: 'h:mm:ss aa',
L: 'MM/DD/YYYY',
LL: 'MMMM D YYYY',
LLL: 'MMMM D YYYY h:mm aa',
LLLL: 'dddd, MMMM D YYYY h:mm aa'

So you can do :

format(
  new Date(2014, 6, 2),
  'LL',
  {locale: this.dateLocales.fr}
)

Those formats are localised

As of 2021, using currently latest version of date-fns (v2.23.0), you can achieve what you want by using the 'P' format.

See: https://date-fns.org/v2.23.0/docs/format

For example, given that today is 2021-08-27 (ISO date):

import { format } from 'date-fns';
import ptBrLocale from 'date-fns/locale/pt-BR';
import enUsLocale from 'date-fns/locale/en-US';

console.log(format(new Date(), 'P', { locale: ptBrLocale }));
console.log(format(new Date(), 'P', { locale: enUsLocale }));

Outputs will be:

27/08/2021
08/27/2021
Related