Moment: get localized format with month and days only

Created on 1 Aug 2016  ·  20Comments  ·  Source: moment/moment

I looked at the locale source files, and could not find a format to display month and day only without year info. One example from locale/zh-cn.js file

longDateFormat : {
    LT : 'Ah点mm分',
    LTS : 'Ah点m分s秒',
    L : 'YYYY-MM-DD',
    LL : 'YYYY年MMMD日',
    LLL : 'YYYY年MMMD日Ah点mm分',
    LLLL : 'YYYY年MMMD日ddddAh点mm分',
    l : 'YYYY-MM-DD',
    ll : 'YYYY年MMMD日',
    lll : 'YYYY年MMMD日Ah点mm分',
    llll : 'YYYY年MMMD日ddddAh点mm分'
},

The list formats all have year. Can you support some format like LM or lm: 'MMMD日'?

Please advise.

Enhancement

Most helpful comment

We use this regular expression to overcome this problem

moment().format('L').replace(new RegExp('[^\.]?' + moment().format('YYYY') + '.?'), '')

It does following conversions
05/04/2017 -> 05/04 (e.g. us, gb)
2017-04-03 -> 04-03 (e.g. swe)
8.7.2017 -> 8.7. (e.g. fin)

All 20 comments

We don't currently offer a localized format token that is month and day only. This would require a significant expansion of the data, as there are likely more than one way to display this in various locales.

It's probably easier to use a custom format instead of trying to fit this into the locale-formats.

I also need this type of format.
I don't want to make it custom as it should correct in all different locales :)

Same here.

Just to consider it, Intl.DateTimeFormat says that implementation should support at least the following subsets: (...) month, day (...). Probably not relevant, but seems it is important to consider it for locale specific messages.

I just had a look at all language files and for most of the languages this seems quite easy...
@mj1856 any ideas how I could get started on this?

@kaljak adding the format is easy, but where are you getting the data for how to properly express this in the given language? You would need a source similar to CLDR, or someone who spoke the language to know that.

Also from here: https://github.com/andyearnshaw/Intl.js/blob/master/locale-data/json/, or from https://github.com/unicode-cldr/cldr-dates-full/ (which also include short/narrow versions for relative times which would be a great addition :)).

Unrelated, but maybe at some point it might make sense to derive locale specific formats from Intl.DateTimeFormat and avoid including the moment specific locale data?

I would need this too.

We use this regular expression to overcome this problem

moment().format('L').replace(new RegExp('[^\.]?' + moment().format('YYYY') + '.?'), '')

It does following conversions
05/04/2017 -> 05/04 (e.g. us, gb)
2017-04-03 -> 04-03 (e.g. swe)
8.7.2017 -> 8.7. (e.g. fin)

+1 on this.

Our website shows something like this in a localized format:
Jan 5

There is not a good way to show this string in a language like Spanish which should look like this:
5 de Jan without slicing off the year text, which seems unmaintainable due to language differences.

I.e. moment().locale('es')format('ll') // 5 de Jan de 2018

@stenvala Awesome solution!

When used with .format('ll') I get a , suffix, how can I fix the above to remove it?

E.g.: Jan 29, 2018 -> Jan 29,

I ran into the same need, and in lieu of a supported way, I put the following code in a helper class that I use inside my services and wrapped in an Angular pipe for use in templates. Your mileage may very, but I reviewed all the locale files and think I got all the different permutations of using the "ll" format as the basis for the new Month & Day format. I've tested against the following locales: en, es, hy-am, hu, cv, ja, lv. Each of those had interesting permutations, including unicode letters in the month names.

if (format.indexOf("YYYY") === 0) {
        // In some locales, the Year is presented first, along with various punctuation (period, comma) as well as sometimes
        // hard coded words in brackets. The RegEx below strips everything off that shouldn't be there related to the YYYY prefix.
        return format.replace(/YYYY(\.)?(\s)?(\[([^\x00-\x7F]|\w)+\])?(\s)?/gi, '');
    }

    // In other locales, the year is presented at the end (or almost end). It can have various punctuation around it as well
    // as hard coded words in brackets. The RegEx below strips everything off that shouldn't be there related to the YYYY suffix.
    return format.replace(/(\s)?,?(\[([^\x00-\x7F]|\w)+\])?(\s)?YYYY.*/gi, '');

Good luck!

PS - I am not a RegEx guru and did my best with the expressions above. They seem to work, but likely could be optimized.

I did .format('MMMDo') to get what I want in the end, not generic but works well in my case.

👍

what about using a data source which has the formatting rule for a lots of languages. The remaining languages get a placeholder text p.ex. 'Hi developer. please report the formatting of your language to the moment.js project. Thanks'

Thus if some developer needs the short date string and uses it, he will get this call to action and the gap is closed on demand.

Here's another workaround using Intl. Customize the options object to get the format you want. Intl.DateTimeFormat will handle all the localized ordering of the strings, and local separators.

const localizedDateMonthNoYear = (moment) => {
    if (window && window.Intl && window.Intl.DateTimeFormat) {
      let options = {
        weekday: 'short',
        month: 'short',
        day: '2-digit',
      }
      return new Intl.DateTimeFormat('default', options).format(moment.toDate())
    }
    return moment.format('ll');
}

Over 3 years, no movement on what is a critical issue that prevents moment.js from being anywhere near considered complete as a date/time formatting library... thank goodness for the Intl API which is slowly becoming standard.

Some of the Moment.js core devs now work on TC39 proposals, because you are right, why not have some of this functionality in the core language?

You can use toLocaleDateString method of JS Date. E.g.

const getFormattedDateTime = dateTime => dateTime.toLocaleDateString('ru-RU', {
  month: 'short',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
})

See https://momentjs.com/docs/#/-project-status/

We will not add new tokens.

Was this page helpful?
0 / 5 - 0 ratings