我在學(xué)習(xí)Fishli李老師的博客時(shí),看到一個(gè)話題,就是DateTime持久化, 還有人駁斥他的文章,弄的我迷糊了,于是花了點(diǎn)時(shí)間,一探究竟,順便做一個(gè)總結(jié) 直接上結(jié)論: * 1. DateTime是結(jié)構(gòu)體
JavaScriptSerializer不能持久化的原因有兩個(gè): 1. 不保存時(shí)差值 2.精度和DateTime的精度不一致 DataContractJsonSerializer和Newtonsoft.Json(版本<=4.5)不能持久化的原因有一個(gè): 1. .精度和DateTime的精度不一致 總結(jié): 不能持久的關(guān)鍵原因?yàn)? "\/Date(991+0800)\/" , 微軟格式的精度和DateTime的精度不一致, 是不是javascript的Date的精度就到毫秒,微軟顧及javascript, 懂的來(lái)說(shuō)說(shuō)吧.. Newtonsoft.Json的行為是這樣的。 <=4.5,也是序列化成微軟的datetime json格式,e.g. "\/Date(1198908717056+0800)\/". >4.5,序列化成ISO標(biāo)準(zhǔn)時(shí)間格式,"2016-05-05T14:59:30.4617225+08:00" , 精確到小數(shù)點(diǎn)7位了, 精度和DateTime一致了
于是我下載了5.0.1版本的Newtonsoft. 試了下, 的確可以持久化了. var settings = new JsonSerializerSettings(); settings.DateFormatHandling = DateFormatHandling.IsoDateFormat; // 如果要輸出ISO標(biāo)準(zhǔn)時(shí)間,可以通過(guò)dateTimeFormat進(jìn)行設(shè)置。 string s0 = JsonConvert.SerializeObject(dt_loc, settings); DateTime Newtonsoft_dt2 = JsonConvert.DeserializeObject<DateTime>(s0); dt_loc == Newtonsoft_dt2 為 true
結(jié)論就是: Newtonsoft.Json(版本>4.5) 能持久化的關(guān)鍵原因就是, 序列化時(shí)采取ISO標(biāo)準(zhǔn), 保存了時(shí)差, 保持了精度,所以反序列化時(shí)才能原原本本的還原. 那篇反駁的文章則驗(yàn)證持久化的方法不對(duì), 他將序列化后的JSON字符結(jié)果放到j(luò)avascript中能夠解析出時(shí)間, 就認(rèn)為持久化沒(méi)有問(wèn)題, 但是他沒(méi)有注意, JSON字符里的Ticks 和 DateTime里的Ticks 精度并不一樣, JSON字符里的Ticks的精度只到1毫秒, 而 DateTime里的Ticks的精確到0.1微秒, 驗(yàn)證持久化最簡(jiǎn)單的辦法就是, 判斷一下Kind是否一致, 再驗(yàn)證一下Ticks是否一致 , 最后就是 dt1 == dt2 是否返回true啊, 他這三個(gè)一個(gè)沒(méi)驗(yàn)證, 竟然就說(shuō)持久化沒(méi)問(wèn)題,太不嚴(yán)謹(jǐn)了,還是嚴(yán)謹(jǐn)點(diǎn)好, 不然理解總是有偏差, 誤導(dǎo)了別人就不好了.
|
|