删除格式 ISO 8601 日期

Format Elided ISO 8601 Date

我在 javascript 变量中有一个 ISO 日期字符串,我想对其进行格式化以便显示。很简单,你可能会想。例如:

new Date(iso).toDateString()

但是,ISO 日期可能只代表一年 ("yyyy"),或一年和一个月 ("yyyy-mm");他们并不总是 "yyyy-mm-dd"。在这种情况下,parse 方法会为缺少的字段填充默认值,这是我不想看到的。

换句话说,我只想格式化 ISO 字符串中定义的日期字段,而不是其他字段。如果 ISO 字符串是“2017-12”,那么我可能希望将其格式化为 12/2012、Dec 2017、December 2017、décembre 2017 之一,具体取决于我的语言环境和详细程度;我不想要日期。同样,如果 ISO 字符串只是“2017”,那么我不想要日期或月份指示。

这个问题主要与省略的 ISO 形式有关,因此不是重复的。

是否有正确格式化此类 ISO 日期的简单方法——最好以区域设置感知方式——还是我必须全部手动完成?

如果您在处理过程中的任何时候都在使用 JavaScript 的原生 Date 类型,那么您就被卡住了;该对象类型只能存储一个瞬间,在内部表示为时间戳 (absolute count of milliseconds since the UNIX epoch, not counting leap seconds)。各种 get* 方法只是根据存储的时间戳计算值,而 set* 方法根据请求的调整计算新的时间戳。如果您将任何内容设置为 NaNundefined,那么时间戳本身将变为 NaN,并且所有 get* 方法同样会 return NaN

如果您要处理日期和时间的不确定或未(未)指定的组件,您最好完全避开 Date;只需使用仅具有已定义值的字段的通用对象,并编写您自己的解析器和格式化程序来匹配。如果您可以提取字符串的相关部分,您可能仍然可以使用本机 Date 方法和对象来处理一些棘手的问题,例如以对区域设置敏感的方式将可能缩写的月份名称转换为数字.

这个解决方案建立在 Mark Reed 的一些评论之上,是我最终采用的解决方案。

默认不支持省略的 ISO 格式(yyyy-mm 或 yyyy)。该要求必须使用 Date 对象才能确定其他输出字段,例如星期几(如果在 ISO 字符串中指定了一天),例如 "Sunday"。但是,Date 对象存储时间戳,因此在解析省略的 ISO 字符串时必须默认缺少的字段。此外,它还需要使用可感知区域设置的库,例如 moment.js.

虽然在解析时会默认缺失的字段,如日或月,但可以在格式化阶段再次剔除,并根据原始剔除的ISO的长度选择相关的格式化字符串字符串.

解决方案应建立在 moment.js 的基础上,为省略的形式定义新的本地化格式字符串(类似于 L、LL、LLL 等),例如LYM/lym 处理 YYYY-MM ISO 大小写。例如:

var LY = "YYYY";        // e.g. 2017
var ly = "YY";
var LYM = "MMMM YYYY";      // e.g. December 2017
var lym = "MMM YYYY";
var LYMD = "dddd MMMM D, YYYY";
var lymd = "ddd MMM D, YYYY";   // e.g. Tuesday December 19, 2017

这些格式化字符串会有效地忽略在解析 ISO 字符串时添加的任何默认字段。