日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

DateTime持久化總結(jié)

 Coder編程 2021-03-15

我在學(xué)習(xí)Fishli李老師的博客時(shí),看到一個(gè)話題,就是DateTime持久化, 還有人駁斥他的文章,弄的我迷糊了,于是花了點(diǎn)時(shí)間,一探究竟,順便做一個(gè)總結(jié)

直接上結(jié)論:

* 1. DateTime是結(jié)構(gòu)體
*
* 2. DateTime.Kind 指明此DateTime 是Utc(協(xié)調(diào)世界時(shí)) 還是 Local(本地時(shí)間) , 但是DateTime里并不保存時(shí)區(qū)和時(shí)差值.
*
* 3. DateTime.Ticks 是0001年1月1日0點(diǎn)0分0秒為原點(diǎn). 精確到 "0.1微秒". 指明計(jì)數(shù)周期 (1Tick = 0.1微秒)
*
* 4. dt1 == dt2, 判斷的依據(jù)是Ticks是否相等, 而不考慮 Kind, 所以會(huì)出現(xiàn)兩種情況: 1.不為同一時(shí)刻, 但值相等. 2.同一時(shí)刻, 但值不相等 .
*
* 5. 序列化時(shí), 以Utc時(shí)間1970年1月1日0點(diǎn)0分0秒0毫秒為原點(diǎn), 精確到 "1毫秒" ,


* 早于原點(diǎn)時(shí)間顯示負(fù)數(shù),例如"\/Date(-112+0800)\/", 晚于原點(diǎn)時(shí)間顯示正數(shù),例如:"\/Date(991+0800)\/" .
*
*
* 假設(shè) dt_loc.Kind = Local , dt_loc.Ticks = 621356256009910001
*
* 等效為: dt_loc.ToUniversalTime().Kind = Utc , dt_loc.ToUniversalTime().Ticks = 621355968009910001
*
* JavaScriptSerializer序列化過(guò)程:
* 計(jì)算生成Utc下的Ticks值=621355968009910001
* 改為以1970年1月1日0點(diǎn)0分0秒0毫秒為時(shí)間原點(diǎn) ,得到 9910001
* 精度從0.1微秒降為1毫秒, (直接砍掉了后四位0001), 得到991
* 序列化為 "\/Date(991)\/"
* 序列化結(jié)果里只包含Utc的Ticks值, 不含Kind和時(shí)差值.
*
*
*
* DataContractJsonSerializer & Newtonsoft.Json (版本<=4.5)  序列化過(guò)程:
* 保持原Ticks值=621356256009910000
* 改為以1970年1月1日0點(diǎn)0分0秒0毫秒為時(shí)間原點(diǎn) ,得到 9910000
* 精度從0.1微秒降為1毫秒, (直接砍掉了后四位0001), 得到991
* 通過(guò)TimeZoneInfo.Local.Id得到時(shí)差值: +0800
* 序列化為 "\/Date(991+0800)\/"
* 序列化結(jié)果里不含Kind, 但包含時(shí)差值,變相保存了時(shí)區(qū)信息、Kind信息(有+0800就是Local,沒(méi)有+0800就是Utc).
*

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ō)吧.. 
 
 
* 后來(lái)在網(wǎng)上查到了下面的資料
* .net自帶的json序列化器,JavaScriptSerializer和DataContractJsonSerializer,都是序列化成微軟的datetime json格式,e.g. "\/Date(1198908717056)\/"

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)了別人就不好了.

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多