<aside> 👉 原文于 2020-07-04 发布在我的博客,2021-03-15 迁移到此处

</aside>


最近在用原生框架开发一个微信小程序,里面涉及不少关于日期的功能,其中一个最简单的功能就是把某个时间转换成年月日去显示。于是我就使用认知中最常用的 new Date(后端返回的时间) 转换成 Date 对象进行处理,再结合自己实现的 formatTime 函数,在开发者工具中也正常显示出了我需要的 YYYY 年 MM 月 DD 日 格式。

看起来一切都很好不是吗?然而如果一切都这么顺利,那就没有这篇文章了。

当我使用开发者工具中的预览功能时,发现在我的 iPhone 11 上显示的却是 NaN 年 NaN 月 NaN 日。这就很神奇了。接着我又尝试了真机调试,发现真机调试上也并没有此问题。目前看来似乎只有开发中的预览版会出现这个问题?但我还是决定解决之,毕竟很多 API 都只有在开发版才能进行测试,我毕竟保证手机端的和开发工具中的保持一致。而且,一个破时间而已,能有多难?

分析问题

首先我需要知道究竟是哪一步导致了 NaN。于是采用了最简单粗暴的方式,在页面 onLoad 时逐步打印我对日期的操作,然后对比预览版的输出和开发者工具中的输出。

console.log(timeFromApi);
console.log(new Date(timeFromApi));
console.log(formatTime(new Date(timeFromApi)));

上面这段代码在开发者工具中输出:

2020-07-01T02:14:53.000+0000
Wed Jul 01 2020 10:14:53 GMT+0800 (China Standard Time)
{year: "2020", month: "07", day: "01", hour: "10", minute: "14", …}

而在手机端输出:

2020-07-01T02:14:53.000+0000
<Date: null>
Object {day:"NaN", hour: "NaN"...}

可以看出是在 new Date() 这一步出现了异常。

问题出在横杠(-)上?

在 Google 上以 new Date js ios 为关键字查找之后,得知 ios 系统下,new Date() 不认字符串中的 -。网上大部分解决方案都是把 - 通过 replace 函数转换成 /,比如 2018-11-11 00:00:00 转换为 2018/11/11 00:00:00,这样就可以被 new Date() 解析了。

但我勾回过头看后端返回的日期格式,是这样的:2020-07-01T02:14:53.000+0000,看起来像是一个 UTC 时间。抱着试一试的心态我也使用了这种方案,果不其然是不可行的,甚至在开发者工具中都报了错,说明仅替换 - 字符得到的字符串都不是一种标准的日期格式了。

dayjs 一把梭!

dayjs 是一个我一直在使用的用来处理日期和时间的第三方库,大小仅为 2kB,轻量且强大。于是我也在项目中安装了 dayjs,并且通过开发者工具编译成了可被引入的 Npm 模块。查了一下文档,如果需要使用 UTC 功能,需要引入单独的插件: