2 min read

IOS 内 Date 对象 Invalid Date 错误的解决方案

最近在更新时间组件的功能的时候,遇到了一个问题:
在 IOS 上,执行以下代码的结果和 Chrome 不一样:

new Date('2016-1-1')

// 在 Chrome 内可以正常返回结果为:
// Fri Jan 01 2016 00:00:00 GMT+0800 (CST)

// 在 IOS 的 Safari 上返回结果为:
// Invalid Date = $1

这就很奇怪,为什么同样的字符串会解析不同呢?

在 MDN 的文档上有如下示例:

new Date('1995-12-17T03:24:00')

看来这一串字符串还要有标准的格式。
MDN 文档内有说明:

dateString
表示日期的字符串值。该字符串应该能被 Date.parse() 方法识别(符合 IETF-compliant RFC 2822 timestamps 或 version of ISO8601)。

因此,'2016-1-1' 并不是一个符合标准的字符串,所以对于标准严格执行并且不做容错处理的 Safari 就报错了。

因此我们就得对这一串字符串做兼容处理了。

可以把字符串补全,比如 '2016-1-1' 变成 '2016-01-01',含有分时的要变成 '2016-01-01T00:00:00',一点都不能错,包括中间的大写的字母 T。

也可以将字符串转换成一组参数,方法如下:

// ES6

const str = '2016-1-1'
new Date(...str.split(/[^0-9]/))

// Safari
// Mon Feb 01 2016 00:00:00 GMT+0800 (CST) = $1

// Chrome
// Mon Feb 01 2016 00:00:00 GMT+0800 (CST)

得益于 ES6 的特性,这种方法的 str 可以是任意类似的时间字符串,包括以中文分割的字符串形式,例如 2016年1月1日12点28分 这种非标准形式的字符串。

new Date(...'2016年1月1日12点28分'.split(/[^0-9]/))

// Chrome
// Mon Feb 01 2016 12:28:00 GMT+0800 (CST)

完美。