我的JSON字符串包含一个返回这样一个值的日期字段:
"2009-04-04T22:55:16.0000000-04:00"
我特别感兴趣的是只解析日期隔间而不是时间。我尝试使用reviver函数,但有趣的是,从不调用reviver函数! (在Firefox上试过)
以下是我的代码:
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);
....
});
}
};
loadArticle
中的JSON.parse从不调用dateReviver
。
答案 0 :(得分:7)
使用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在每个属性上调用。 reviver逻辑是检查属性是否是字符串类型,如果是,它是否看起来像日期的开始... 如果它是一个日期,那么让新的日期(值)进行实际的解析......所有时区的变化都是这样支持的。
希望它有所帮助!
答案 1 :(得分:4)
正则表达式需要一个“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
答案 2 :(得分:3)
扩展jQuery.ajax转换器设置对我来说是正常的,默认为:
"text json": jQuery.parseJSON
到
"text json": function (xmlValue) {
var value = JSON.parse(xmlValue, Site.dateReviver);
return value;
}
答案 3 :(得分:2)
使用return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));
不会调整时区信息的日期,例如-4:00
。
另一种方法是让Date()为你解析:
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)。
答案 4 :(得分:0)
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;
}
答案 5 :(得分:0)
嵌入式解决方案
const jsonDateRegexp = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d{3})Z$/;
function jsonRetriever(key: string, value: any) {
// let's try to detect input we dont have to parse early, so this function is as fast as possible
if (typeof value !== 'string') {
return value;
}
const dateMatch = jsonDateRegexp.exec(value);
if (!dateMatch) {
return value;
}
return new Date(
Date.UTC(
+dateMatch[1],
+dateMatch[2] - 1,
+dateMatch[3],
+dateMatch[4],
+dateMatch[5],
+dateMatch[6],
+dateMatch[7],
),
);
}
export function parseJsonWithDates(input: string) {
return JSON.parse(input, jsonRetriever);
}