Intl formatRange输出斜杠替代日文年月日字面量的配置咨询
问题说明
使用日语ja区域设置时,Intl.DateTimeFormat的formatRange、formatRangeToParts方法默认输出的分隔字面量,和单日期格式化方法format、formatToParts的输出不一致:
- 预期输出:
2022年7月13日 ~ 2022年7月14日 - 实际输出:
2022/07/13~2022/07/14
复现代码:
const options = { month: 'short', day: 'numeric', year: 'numeric' } , from = new Date('2022-07-13T12:00:00Z') , to = new Date('2022-07-14T12:00:00Z') , withLiterals = Intl.DateTimeFormat('ja', options).format(from) , withSlashLiteral = Intl.DateTimeFormat('ja', options).formatRange(from, to) , singleDateParts = Intl.DateTimeFormat('ja', options).formatToParts(from) , rangeParts = Intl.DateTimeFormat('ja', options).formatRangeToParts(from, to) , onlyLiterals = ({ type, value }) => type === 'literal' ? value : '' console.log('format\t\t\t= working literals\t', withLiterals) console.log('formatRange\t\t= slash literals\t', withSlashLiteral) console.log('formatToParts\t\t= working literals\t', singleDateParts.map(onlyLiterals).join('')) console.log('formatRangeToParts\t= slash literals\t', rangeParts.map(onlyLiterals).join(''))
调试用样式:
.as-console-wrapper {max-height: 100% !important;top: 0;} .as-console-row::after {display: none !important;}
原因说明
该表现是符合规范的预期行为,不是实现bug:
- 所有
IntlAPI的区域格式规则均来自Unicode CLDR(通用区域数据仓库)。日语区域下的日期范围格式化规则和单日期格式化规则是独立配置的:针对中等/短长度的日期格式,范围格式化默认使用/作为分隔符输出紧凑样式,减少重复字符,这是日语场景下通用的简略日期写法,常见于表格、日志、紧凑排版场景,属于面向日语使用者的规范格式。 - 传入
{year:'numeric', month:'short', day:'numeric'}配置时,单日期格式化会匹配到带「年」「月」「日」汉字的格式规则,范围格式化则匹配到斜杠分隔的紧凑规则,因此出现字面量不一致的情况。
实现方案
如果需要输出带「年」「月」「日」汉字的正式日期范围格式,可选择以下两种方式:
- 直接使用长日期格式配置:初始化
Intl.DateTimeFormat时传入dateStyle: 'long'参数,范围格式化会自动输出汉字分隔的格式,结果为2022年7月13日~2022年7月14日,和单日期长格式表现一致。 - 手动拼接自定义格式:如果需要精确控制输出样式,可通过
formatRangeToParts获取分段的年、月、日数值,丢弃默认返回的斜杠字面量,手动拼接「年」「月」「日」和范围分隔符。这种方式不受运行环境内置CLDR版本差异影响,输出结果最稳定。
内容的提问来源于stack exchange,提问作者andyb
相关产品推荐
相关产品推荐

