How to get a list of month names in javascript using Intl

Viewed 5181

How can I get a list of all long month names using the ECMAScript Internationalization API?

For example, if the user's locale is en-US, I'd like to get the following:

["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
4 Answers

This should do it:

function getMonthsForLocale(locale) {
    var format = new Intl.DateTimeFormat(locale, { month: 'long' })
    var months = []
    for (var month = 0; month < 12; month++) {
        var testDate = new Date(Date.UTC(2000, month, 1, 0, 0, 0));
        months.push(format.format(testDate))
    }
    return months;
}

My solution in 2021 with es6 Syntax

/**
 * Return list of months
 *  localeName   : name of local, f.e. en-GB, default es-MX
 *  ✅ monthFormat : short, numeric, long (Default)
 */
function monthsForLocale(localeName = 'es-MX', monthFormat = 'long') {
  const format = new Intl
     .DateTimeFormat(localeName, {month: monthFormat}).format;
  return [...Array(12).keys()]
    .map((m) => format(new Date(Date.UTC(2021, (m+1)%12))));
}


//  Testing:

// ['enero', ..., 'noviembre','diciembre' ]
console.log(monthsForLocale());

// ['1', '2',  '3', '4',  '5', '6',  '7', '8',  '9', '10', '11', '12']
console.log(monthsForLocale('en-GB', 'numeric'));

// ['Jan', 'Feb','Mar', 'Apr', 'May','Jun', 'Jul', 'Aug','Sep', 'Oct', 'Nov','Dec' ]    
console.log(monthsForLocale('en-GB', 'short'));

// ['1月',  '2月', '3月',  '4月',  '5月','6月',  '7月',  '8月','9月',  '10月', '11月', '12月']
console.log(monthsForLocale('ja-JP', 'short'));

To make this work on Safari as well, we need to offset by an additional day (Dates in Safari appear off by one using Intl.DateTimeFormat with en-US locale). This works in our usecase because we are just getting the month names, so it does not matter if we generate the string from the 1st or the 2nd of the month.

const SAFARI_OFFSET_FIX = 1;
const getMonthsForLocale = (locale = navigator.language) => {
  const format = new Intl.DateTimeFormat(locale, { month: 'long' });
  const months = [];
  for (let month = 0; month < 12; month++) {
    const testDate = new Date(0, month, 1 + SAFARI_OFFSET_FIX, 0, 0, 0);
    months.push(format.format(testDate));
  }
  return months;
};

Combining the best of the answers above, plus my own small improvements.

Usually people want a list of months to start with January, not December. Switching from new Date(Date.UTC(2021, m))) to simply new Date(2021, m)) resolves this, as it creates a date in the user's own locale.

/**
 * Get a list of the 12 months of the year as strings, according to specified locale and format
 * @typedef {Object} Options
 * @property {string} [locale=navigator.language] : name of locale, e.g. en-GB, defaults to 
 *   the user's own locale
 * @property {string} [monthFormat="long"] : "short", "numeric", or "long" (default)
 *
 * @param {Options} [options] : input options
 * @return {string[]} : an array of 12 strings, the months of the year in the requested format
 */
function getAllMonths({ locale = navigator.language, format = "long"} = {}) {
  const applyFormat = new Intl.DateTimeFormat(locale, { month: format }).format;
  return [...Array(12).keys()].map((m) => applyFormat(new Date(2021, m)));
}

// Testing in en-US locale
console.log(getAllMonths());
// ["January", "February", ... "December"]
console.log(getAllMonths({ format: "numeric" }));
// ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]
console.log(getAllMonths({ format: "short" }));
// ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"]
console.log(getAllMonths({ locale: "es-mx" }));
// ["enero", "febrero", ... "diciembre"]
console.log(getAllMonths({ locale: "ja-JP", format: "short" }));
// ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
Related