如何使用 ECMAScript 国际化 API 获取所有长月份名称的列表?
例如,如果用户的区域设置是
en-US
,我想得到以下信息:
["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
/**
* 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'));
这应该可以做到:
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;
}
为了使此功能在 Safari 上也能正常工作,我们需要额外抵消一天 (使用 Intl.DateTimeFormat 和 en-US 区域设置,Safari 中的日期会显示相差一)。 这在我们的用例中有效,因为我们只是获取月份名称,因此我们是否从该月的第 1 号或第 2 号生成字符串并不重要。
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;
};
通常人们想要一个从一月开始的月份列表,而不是从十二月开始。从
new Date(Date.UTC(2021, m)))
切换到简单的
new Date(2021, m))
可以解决此问题,因为它会在用户自己的区域设置中创建日期。
/**
* 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月"]
向
format
DateTimeFormat 选项添加时区属性,以将时区属性锁定为 UTC。
const getMonths = (language) => {
const monthIndexes = [...Array(12).keys()]
const options = {
month: 'long',
timeZone: 'UTC', // Add this
}
const applyFormat = new Intl.DateTimeFormat(language, options).format;
return monthIndexes.map((m) => applyFormat(new Date(Date.UTC(0, m))));
}
getMonths('en')
// (12) ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
getMonths('zh')
// (12) ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']