如何通过Intl.DateTimeFormat的month属性设置不同长度的月份名称显示方式?
- 内容介绍
- 相关推荐
本文共计824个文字,预计阅读时间需要4分钟。
很多人以为month选项能直接控制几月还是几月几日,结果发现输出的结果是3或03,基本不是三月或Mar。这是因为这两个值明确表示数字形式,和月份名称完全无关。
要显示名称,必须用 'long'、'short' 或 'narrow' —— 它们才是专为文本设计的值。
-
'long':输出完整月份名,如'March'(en-US)、'三月'(zh-CN) -
'short':缩写,如'Mar'、'3月' -
'narrow':极简单字母/字,如'M'、'3'(注意:中文里通常仍是'3',不是字)
locale 和 numberingSystem 共同决定中文是否显示“三月”而非“3月”
中文环境下,Intl.DateTimeFormat('zh-CN', { month: 'short' }) 默认输出 '3月',不是 '三月'。这不是 bug,而是默认使用阿拉伯数字编号系统(numberingSystem: 'latn')。
想强制用汉字数字,得显式指定 numberingSystem: 'hanidec':
new Intl.DateTimeFormat('zh-CN', { month: 'long', numberingSystem: 'hanidec' }).format(new Date(2024, 2)) // → '三月'
但要注意:'hanidec' 在部分浏览器(如旧版 Safari)支持不稳;且 'narrow' 模式下即使设了 hanidec,仍可能回退为数字。
month: 'narrow' 在不同 locale 下行为差异大,慎用于 UI 显示
'narrow' 看似省空间,实际兼容性最差。英文 locale 下它可能返回单字母('J', 'F'),但这些字母在不同语言里未必唯一(比如 'M' 可能是 March / May / June 的首字母)。
中文 locale 下,'narrow' 基本等价于 'numeric',返回 '1'~'12',无法区分“一月”和“十一月”——因为汉字单字缩写无通用规范。
- 别用
'narrow'做可交互的月份选择器标签 - 若真需极简,优先用
'short'+ CSS 控制宽度,更可控 - 测试时务必覆盖目标 locale,不能只看 en-US
格式化结果依赖完整日期对象,单独传 month 不生效
常见错误是试图只传一个数字月份给 format():
const fmt = new Intl.DateTimeFormat('ja-JP', { month: 'long' }); fmt.format(3); // ❌ 报错或返回无效字符串
Intl.DateTimeFormat.prototype.format() 只接受 Date 实例(或时间戳毫秒数)。月份值必须嵌在日期中:
fmt.format(new Date(2024, 2, 1)); // ✅ '3月'(注意:month 是 0-indexed)
如果只有月份数字(如后端返回 3),必须手动构造日期对象,且注意 new Date(year, monthIndex) 中 monthIndex 是从 0 开始的 —— 直接传 3 会变成四月。
'zh-cn' 可能降级为默认 locale),以及 numberingSystem 的隐式 fallback 行为。别假设“设了就一定生效”,尤其在混合多语言的 SSR 场景中。本文共计824个文字,预计阅读时间需要4分钟。
很多人以为month选项能直接控制几月还是几月几日,结果发现输出的结果是3或03,基本不是三月或Mar。这是因为这两个值明确表示数字形式,和月份名称完全无关。
要显示名称,必须用 'long'、'short' 或 'narrow' —— 它们才是专为文本设计的值。
-
'long':输出完整月份名,如'March'(en-US)、'三月'(zh-CN) -
'short':缩写,如'Mar'、'3月' -
'narrow':极简单字母/字,如'M'、'3'(注意:中文里通常仍是'3',不是字)
locale 和 numberingSystem 共同决定中文是否显示“三月”而非“3月”
中文环境下,Intl.DateTimeFormat('zh-CN', { month: 'short' }) 默认输出 '3月',不是 '三月'。这不是 bug,而是默认使用阿拉伯数字编号系统(numberingSystem: 'latn')。
想强制用汉字数字,得显式指定 numberingSystem: 'hanidec':
new Intl.DateTimeFormat('zh-CN', { month: 'long', numberingSystem: 'hanidec' }).format(new Date(2024, 2)) // → '三月'
但要注意:'hanidec' 在部分浏览器(如旧版 Safari)支持不稳;且 'narrow' 模式下即使设了 hanidec,仍可能回退为数字。
month: 'narrow' 在不同 locale 下行为差异大,慎用于 UI 显示
'narrow' 看似省空间,实际兼容性最差。英文 locale 下它可能返回单字母('J', 'F'),但这些字母在不同语言里未必唯一(比如 'M' 可能是 March / May / June 的首字母)。
中文 locale 下,'narrow' 基本等价于 'numeric',返回 '1'~'12',无法区分“一月”和“十一月”——因为汉字单字缩写无通用规范。
- 别用
'narrow'做可交互的月份选择器标签 - 若真需极简,优先用
'short'+ CSS 控制宽度,更可控 - 测试时务必覆盖目标 locale,不能只看 en-US
格式化结果依赖完整日期对象,单独传 month 不生效
常见错误是试图只传一个数字月份给 format():
const fmt = new Intl.DateTimeFormat('ja-JP', { month: 'long' }); fmt.format(3); // ❌ 报错或返回无效字符串
Intl.DateTimeFormat.prototype.format() 只接受 Date 实例(或时间戳毫秒数)。月份值必须嵌在日期中:
fmt.format(new Date(2024, 2, 1)); // ✅ '3月'(注意:month 是 0-indexed)
如果只有月份数字(如后端返回 3),必须手动构造日期对象,且注意 new Date(year, monthIndex) 中 monthIndex 是从 0 开始的 —— 直接传 3 会变成四月。
'zh-cn' 可能降级为默认 locale),以及 numberingSystem 的隐式 fallback 行为。别假设“设了就一定生效”,尤其在混合多语言的 SSR 场景中。
