JavaScript端的JSON日期轉換

討論JSON日期轉換已不是第一次[1 2],但過去多半聚焦在JavaScript與.NET間的格式轉換。近來戰場移到Knockout MVVM,卻發現即使只在JavaScript端,也有日期轉換的小眉角。

在JavaScript的Date型別,經過JSON.stringify(),會轉成ISO 8601格式(yyyy-MM-ddTHH:mm:ss.fffZ);有趣的是,將這個字串用JSON.parse()解析,得到的是字串,而不會還原成當初的Date型別。

將ISO 8601格式還原回Date的需求,要透過JSON.parse()的Reviver函數實現。範例如下:

var d = new Date();
//預設Date會轉為yyyy-MM-ddTHH:mm:ss.fffZ ISO 8601格式
var t = JSON.stringify(d);
console.log(t);
//parse時,ISO 8601格式並不會被轉成Date,而是被視為字串
console.log(typeof (JSON.parse(t)));
//透過reviver提供ISO 8601字串轉Data的功能
//REF: http://msdn.microsoft.com/zh-tw/library/ie/cc836466(v=vs.94).aspx
var 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;
};
var result = JSON.parse(t, dateReviver);
console.log("type=" + typeof (result) + ", value=" + result.toString());
//同場加映: 排除特定屬性及修改屬性值
var obj = {
    boo: "BOO",
    foo: "FOO",
    blah: "BLAH"
};
t = JSON.stringify(obj);
console.log(t);
//客製Reviver,忽略boo,並在foo的內容後方加上"*"
var myReviver = function (key, value) {
    //傳回null或undefined會刪除該屬性
    if (key == "boo") return undefined;
    if (key == "foo") return value + "*";
    return value;
};
result = JSON.parse(t, myReviver);
console.log(JSON.stringify(result));

線上展示: http://jsfiddle.net/darkthread/8yC8m/

由執行結果可以看到Date在JSON.stringify()後被轉成"2013-05-10T14:07:46.761Z",但JSON.parse()的型別卻是string不是Date。接著我們宣告一個dateReviver函數,偵測當輸入字串格式為ISO 8601時,則拆解其中的年、月、日、時、分、秒還原回Date。另外,順道示範Reviver可以依屬性名稱執行不同邏輯(由key參數判斷),以及忽略某個屬性(return undefined)的能力。

歡迎推文分享:
Published 11 May 2013 07:54 AM 由 Jeffrey
Filed under:
Views: 15,260



意見

# player said on 13 June, 2013 11:54 AM

如果是經過jQuery去抓資料的話, 可以用這個

www.wiredprairie.us/.../1183

# Jeffrey said on 14 June, 2013 06:39 AM

to player, 從源頭改是不錯的攔截點,謝謝補充。

該案例置換的是微軟的日期格式”\/Date(1297031297600)\/”,此種格式不會出現在一般字串JSON後的內容中,ISO 8601的內容則未分能100%斷定是一般字串或是日期物件轉換的結果,故存在誤轉的風險。

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<May 2013>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication