react-native 日期格式化

今天在 react native 项目中,遇到了一个日期格式化的问题,做下笔记

问题

当App开启调试模式时

1
let date = new Date('2018-07-07T22:44:14.000+0800'); // Sat Jul 07 2018 22:44:14 GMT+0800 (中国标准时间)

就这样很开心提交代码打包。第二天发现客户端显示日期不对,显示 Invalid Date,😫。
经过重复实验,发现
当关闭调试模式

1
let date = new Date('2018-07-07T22:44:14.000+0800'); // Invilid Date

终于重现问题。

原因

调试是使用的是 Chrome 的 V8 Javascript 引擎,关闭调试使用的是 iOS 的 JavascriptCore Javascript 引擎。这两个引擎在实现上还是有区别。
https://github.com/facebook/react-native/issues/15819#issuecomment-327273365

解决

后来找了个对这种格式时间进行解析的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Date.prototype.setISO8601 = function (string) {
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
"(Z|(([-+])([0-9]{2})([0-9]{2})))?)?)?)?";
if (string) {
var d = string.match(new RegExp(regexp));
var offset = 0;
var date = new Date(d[1], 0, 1);

if (d[3]) {
date.setMonth(d[3] - 1);
}
if (d[5]) {
date.setDate(d[5]);
}
if (d[7]) {
date.setHours(d[7]);
}
if (d[8]) {
date.setMinutes(d[8]);
}
if (d[10]) {
date.setSeconds(d[10]);
}
if (d[12]) {
date.setMilliseconds(Number("0." + d[12]) * 1000);
}
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
time = (Number(date) + (offset * 60 * 1000));
this.setTime(Number(time));
}
else {
return;
}
}

使用

1
2
let date = new Date();
date.setISO8601('2018-07-07T22:44:14.000+0800'); // Sat Jul 07 2018 22:44:14 GMT+0800 (中国标准时间)

终于跟调试模式输出一样了

再来个日期格式化方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//日期格式化
Date.prototype.format = function (fmt) {
var o = {
"M+": this.getMonth() + 1,
"d+": this.getDate(),
"h+": this.getHours(),
"m+": this.getMinutes(),
"s+": this.getSeconds(),
"q+": Math.floor((this.getMonth() + 3) / 3),
"S": this.getMilliseconds()
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}

使用

1
2
3
let date = new Date();
date.setISO8601('2018-07-07T22:44:14.000+0800'); // Sat Jul 07 2018 22:44:14 GMT+0800 (中国标准时间)
let formatedDate = date.format("yyyy年MM月dd日"); // 2018年07月07日

完美