2013年6月19日 星期三

JavaScriptSerializer 日期處理

使用JavaScriptSerializer序列化日期時,格式會長的像\/Date(ticks)\/這個樣子
其中的tick為1970/1/1到目前為止的毫秒數
因為沒有時區資訊,而且預設會轉換成UTC時間
所以反序列化回來的時後,會有時區的問題
string jsonString = string.Empty;
DateTime d1 = DateTime.Now;

JavaScriptSerializer jss = new JavaScriptSerializer();
jsonString = jss.Serialize(d1);
Console.WriteLine(jsonString);

DateTime d2 = jss.Deserialize<DateTime>(jsonString);
Console.WriteLine("d1:{0}, kind:{1}", d1, d1.Kind);
Console.WriteLine("d2:{0}, kind:{1}", d2, d2.Kind);
Console.ReadLine();
執行結果如下
解決方法很簡單,反序列化回來的時後,記得把時間ToLocalTime就好了
string jsonString = string.Empty;
DateTime d1 = DateTime.Now;

JavaScriptSerializer jss = new JavaScriptSerializer();
jsonString = jss.Serialize(d1);
Console.WriteLine(jsonString);

DateTime d2 = jss.Deserialize<DateTime>(jsonString).ToLocalTime();
Console.WriteLine("d1:{0}, kind:{1}", d1, d1.Kind);
Console.WriteLine("d2:{0}, kind:{1}", d2, d2.Kind);
Console.ReadLine();
執行結果如下

另外一個問題是傳到JavaScript的時後,只會把這樣的格式當成字串,需要自行拆解
打開一個Chrome的主控台來測試一下,輸入以下幾行指令
// 建立一個JSON格式的資料
data = { "today": "\/Date(1371631612818)\/" };

// 看一下資料解析的樣子
data.today;

// 把前後的斜線去掉的樣子
data.today.replace(/\//g, "");

// 使用eval來得到日期
eval("new " + data.today.replace(/\//g, ""))

// 使用reg取出ticks的部份
data.today.replace(/\/Date\((\d+)\)\//g, "$1");

// parseInt轉成數字後也能得到日期
new Date(parseInt(data.today.replace(/\/Date\((\d+)\)\//g, "$1")))
執行結果如下