Luxon DateTime.toFormat('t')生成非断空格问题及解决方法咨询
如何让Luxon使用自带格式't'时输出普通空格而非非断空格?
在从MomentJS迁移到Luxon的过程中,实现BusinessHours的getter方法时,用Luxon的toFormat('t')替代Moment的format('LT')后,Jest测试失败。原因是toFormat('t')生成的时间字符串中,数字和AM/PM之间是非断空格(NNBSP,Unicode编码\u00A0),而测试预期是普通空格。手动改用h:mm a格式可以解决问题,但希望能保留使用Luxon自带格式t的方式。
相关代码
迁移后的Luxon代码:
get KeyBusinessHours(): string { if (this.Report.Type === ReportType.InternetHealth) { let start = DateTime.fromMillis(0); start = start.plus(GetDurationAmount('minutes', this.Options['KeyBusinessHoursStart'])); let end = DateTime.fromMillis(0); end = end.plus(GetDurationAmount('minutes', this.Options['KeyBusinessHoursEnd'])); // 不转换到用户时区,仅展示所选时间及对应时区 - 使用UTC return `${start.toUTC().toFormat('t')} - ${end.toUTC().toFormat('t')}${this.Options['TimezoneForReport'] != null ? `(${this.Options['TimezoneForReport']})` : ''}`; } return undefined; }
原MomentJS代码:
get KeyBusinessHours(): string { if (this.Report.Type === ReportType.InternetHealth) { let start = moment(0); start.add(this.Options['KeyBusinessHoursStart'], 'minutes'); let end = moment(0); end.add(this.Options['KeyBusinessHoursEnd'], 'minutes'); // 不转换到用户时区,仅展示所选时间及对应时区 - 使用UTC return `${start.utc().format('LT')} - ${end.utc().format('LT')} (${this.Options['TimezoneForReport']})`; } return undefined; }
测试失败信息
Expected substring: "2:00 AM - 4:00 AM" Received string: "2:00 AM - 4:00 AM"
解决方案
Luxon的't'格式对应本地化配置中的shortTime,默认使用非断空格是符合部分地区排版规范的,但可以通过以下方式修改为普通空格:
1. 全局修改本地化格式
通过Settings.updateLocale修改对应语言的shortTime格式,将其中的非断空格替换为普通空格。以英文(en-US)为例:
import { Settings } from 'luxon'; // 先设置默认locale(如果项目已设置可省略) Settings.defaultLocale = 'en-US'; // 更新locale的shortTime格式 Settings.updateLocale('en-US', { formats: { shortTime: 'h:mm a' } });
修改后,所有调用toFormat('t')的地方都会使用你定义的格式,输出普通空格,一劳永逸适配整个项目。
2. 格式化后局部替换空格
如果不想修改全局配置,可在格式化完成后直接替换非断空格:
// 替换单个时间字符串的非断空格 start.toUTC().toFormat('t').replace(/\u00A0/g, ' ')
在你的getter方法中修改为:
return `${start.toUTC().toFormat('t').replace(/\u00A0/g, ' ')} - ${end.toUTC().toFormat('t').replace(/\u00A0/g, ' ')}${this.Options['TimezoneForReport'] != null ? `(${this.Options['TimezoneForReport']})` : ''}`;
这种方式更灵活,适合仅局部需要替换的场景。
3. 自定义格式别名(兼容Moment用法)
可以自定义一个和Moment一致的'LT'格式别名,配置到本地化中:
Settings.updateLocale('en-US', { formats: { LT: 'h:mm a' } });
之后就可以像Moment一样使用toFormat('LT'),输出带普通空格的时间字符串,减少迁移后的代码改动。
内容的提问来源于stack exchange,提问作者IMeyers20
相关产品推荐
相关产品推荐

