首页 > 解决方案 > 如何解析从 Intl.DateTimeFormat 生成的日期字符串

问题描述

使用Intl.DateTimeFormat.format函数,您可以生成针对特定语言环境格式化的日期字符串。传递给Intl.DateTimeFormat.format()函数的选项允许了解有关格式的一些信息,例如,如果年份是两位数或四位数字,但有些事情是未知的,例如使用的分隔符或年、月和日元素的顺序.

尝试将字符串解析回Date对象并不总是可以使用Date.parse.

例如,此代码在西班牙语语言环境中失败,但适用于英语:

const date = new Date(2020, 10, 28);

const regionEs = new Intl.DateTimeFormat('es', { timeZone: 'UTC' });
const regionEn = new Intl.DateTimeFormat('en', { timeZone: 'UTC' });

const stringEs = regionEs.format(date); // "28/11/2020"
const stringEn = regionEn.format(date); // "11/28/2020"

const parseEs = new Date(Date.parse(stringEs)); // Error -> Trying to set month to 28
const parseEn = new Date(Date.parse(stringEn)); // Ok

但是,如果用于生成字符串的格式模板可以从以下位置获得,则可能很容易Intl: 类似"dd/mm/yyyy". 通过这种方式,字符串可以安全地拆分为可用于构建Date对象的部分。问题是似乎无法从Intl.DateTimeFormat.

[Intl.resolvedOptions()][1]方法没有提供任何帮助,因为它只是提供了传递给构造函数的选项以及默认值。

问题

有没有办法在不使用或任何其他外部库的情况下将格式化的字符串解析Intl回对象?Datemoment.js

我的用例

我正在使用一个日期时间组件,它接受格式和解析函数来处理日期。当用户使用日期时间输入的日历控件选择日期时,没有问题,并且格式化函数用于Intl根据区域设置和一组格式选项对其进行格式化。有时用户手动编辑显示的日期。如果使用西班牙语言环境,他可以看到"27/11/2020"显示的日期,他决定将日期更改为"28/11/2020". 这将失败,因为Date.parse()无法解析此日期(见上文)。这在其他地区可能会变得更糟。我试图避免包含外部日期库,但没有找到解决此问题的方法。我知道用户可以以任意格式编辑日期,但我希望至少接受控件中显示的相同格式,我认为这是最友好的 UI,因为始终显示默认日期。

标签: javascriptdatedatetimeinternationalization

解决方案


当然你可以使用moment.js这样的东西,但你需要知道你正在使用的每个区域的格式,根据你的代码

const parseEs = moment("28/11/2020", "DD/MM/YYYY");
const parseEn = moment("11/28/2020", "MM/DD/YYYY");

最后moment提供toDate()功能,因此您可以再次将其传递为区域格式(以防您使用任何组件或库添加/减去或编辑日期)

const stringEs = regionEs.format(parseEs.toDate()); // "28/11/2020"
const stringEn = regionEn.format(parseEn.ToDate()); // "11/28/2020"

推荐阅读