如何使用 JSON.parse reviver 参数解析日期字符串
-
22-09-2019 - |
题
我的 JSON 字符串包含一个返回这样值的日期字段:
"2009-04-04T22:55:16.0000000-04:00"
我对仅解析日期部分而不是时间特别感兴趣。我尝试使用 reviver 函数,但有趣的是,reviver 函数从未被调用!(在火狐浏览器上尝试过)
这是我的代码来实现这一点:
var Site = {
.....
dateReviver: function(key, value) {
var a;
if (typeof value === 'string') {
a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
},
loadArticle: function(id) {
....
proxy.getArticle(id, function(response) {
var data = JSON.parse(response.result, Site.dateReviver);
....
});
}
};
JSON.parse in loadArticle
从不打电话 dateReviver
.
我投入了一整天但没有运气!有人可以帮我吗?
解决方案
正则表达式需要“Zulu”时区(末尾有“Z”字符),而示例日期时间字符串显示数字时区(“-04:00”)。以下正则表达式将接受两者:
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(Z|([+\-])(\d{2}):(\d{2}))$/
如果时区数字不为零,您可能需要在解析和/或转换为 UTC 后实际修改日期,以尊重时区。
我可以看到 dateReviver() 被击中。在浏览器中尝试以下操作:
<!-- saved from url=(0014)about:internet --> <html> <head> <script src="http://www.json.org/json2.js"></script> <script type="text/javascript" src="http://ajax.Microsoft.com/ajax/jQuery/jquery-1.3.2.js"></script> <script> $(function () { // a mock proxy to return some json to play with var proxy = { getArticle: function(id, foo) { foo({ result: '["2009-04-04T22:55:16.0000000-04:00"]' }); } }; // the origial Site object, with the fixed regex var Site = { dateReviver: function(key, value) { var a; if (typeof value === 'string') { a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(Z|([+\-])(\d{2}):(\d{2}))$/.exec(value); if (a) { return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])); } } return value; }, loadArticle: function(id) { proxy.getArticle(id, function(response) { var data = JSON.parse(response.result, Site.dateReviver); // put the parsed JSON date on the page $("#output").html(data[0].toString()); }); } }; // try out our Site object Site.loadArticle(); }); </script> </head> <body> <div id="output"></div> </body> </html>
我在浏览器中看到以下内容,表明解析成功:
Sat Apr 4 15:55:16 PDT 2009
其他提示
使用TypeSript,我的解决方案如下:
export function parseWithDate(jsonString: string): any {
var reDateDetect = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/; // startswith: 2015-04-29T22:06:55
var resultObject = JSON.parse(jsonString,(key: any, value: any) => {
if (typeof value == 'string' && (reDateDetect.exec(value))) {
return new Date(value);
}
return value;
});
return resultObject;
}
世界上最好的;-) 它使用了一个匿名datereviver,它获取由JSON.parse每个属性调用。 齐磊的逻辑是检查属性是否为字符串类型,如果是这样,无论它看起来像一个约会的开始...... 如果它是一个日期,然后让新的日期(值)做实际的解析......所有时区的变化都支持这种方式。
希望它能帮助!
扩展jQuery.ajax转换器设置其默认的工作对我罚款:
"text json": jQuery.parseJSON
到
"text json": function (xmlValue) {
var value = JSON.parse(xmlValue, Site.dateReviver);
return value;
}
在使用return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));
的
不会在例如调整日期为时区信息,该-4:00
。
另一种方法是让日期()做解析为你:
var dateReviver = function (key, value) {
var a;
if (typeof value === 'string') {
a = Date.parse(value);
if (a) {
return new Date(a);
}
}
return value;
}
如果将JSON已格式化JSON.stringify()它会一直在UTC(Z)。
function dateReviver (k,v) {
var isnum = /^\d+$/.test(v);
// Check if number since Date.parse(number) returns valid date
if (isnum) {
return v;
}
if (Date.parse(v)) {
return new Date(Date.parse(v));
}
return v;
}
不隶属于 StackOverflow