[英]How to use JSON.parse reviver parameter to parse date string
我的 JSON 字符串包含返回這樣一個值的日期字段:
"2009-04-04T22:55:16.0000000-04:00"
我對只解析日期隔間而不是時間特別感興趣。 我嘗試使用 reviver function,但有趣的是 reviver function 從未被調用! (在 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 中的loadArticle
從不調用dateReviver
。
我投資了一整天但沒有運氣? 有人可以幫我嗎?
使用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 邏輯是檢查屬性是否是字符串類型,如果是,它是否看起來像一個日期的開始......如果它是一個日期,那么讓 new Date(value) 做實際的解析......所有以這種方式支持時區變化。
希望能幫助到你!
正則表達式需要一個“祖魯語”時區(末尾有一個 '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
從默認情況下,擴展 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
。
另一種方法是讓 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)。
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;
}
嵌入式解決方案
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);
}
我今天遇到了這個問題,我的方法與其他人提供的方法不同。
如果您提前知道包含日期的密鑰,則可以像這樣編寫 reviver:
export const jsonDateReviver = (keysToParse: Record<string, boolean>) => (key: string, value: any) => {
if (keysToParse[key]) {
if (Array.isArray(value)) {
return value.map(v => new Date(v));
}
return new Date(value);
}
return value;
};
然后你可以像這樣使用它:
JSON.parse(data, jsonDateReviver({ lastModifiedAt: true }))
或者你可以有一個全局keysToParse
object 而不是每次都重新定義它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.