海南网站开发,谷歌广告联盟,物流网站哪个好,企业宣传片制作哪家好C#中的DateTime在逻辑上有个非常严重的缺陷#xff1a; var d DateTime.Now; var d2 d.ToUniversalTime(); d d2false d.Equals(d2);false在C#交互模式中输入以上代码#xff0c;可以发现尽管一个是本地时间#xff08;d#xff09;#xff0c;一个是U… C#中的DateTime在逻辑上有个非常严重的缺陷 var d DateTime.Now; var d2 d.ToUniversalTime(); d d2false d.Equals(d2);false在C#交互模式中输入以上代码可以发现尽管一个是本地时间d一个是UTC时间(d2)只是时区不一样但在这个世界上应该属于同一个时刻。然而两个时间却不相等。。。原因在于DateTime不存储时区或者说只存储了一个模糊的关于时区的字段Kind它是DateTimeKind枚举类型的有三种取值Utc/Local/Unspecified当取值为Unspecified时则会有歧义。但我还是要吐槽如果d.Kind或d2.Kind中任意一个是Unspecified那么d ! d2我可以理解。但是上面的d.Kind是Locald2.Kind是Utc如果按照DateTime不存储时区的逻辑那么这两个统一转换Utc或者Local时那么它们应该相等事实上也是如此 d d2.ToLocalTime()true如果把d的本地时间t1当做9本地时间所处时区z1当做8相应的UTC时间t0当做1UTC时间所处时区z0当做0对它们做规范化处理那么 d t1-z1 9 - 8 1, d2 t0 - z0 1 - 0 1 。然而 d ! d2。这才是它怪异的地方。以东八区为例在C#交互模式中输入以下代码 var d3 new DateTime(2018, 1, 1); d3[2018/1/1 0:00:00] d3.ToLocalTime()[2018/1/1 8:00:00] d3.ToUniversalTime()[2017/12/31 16:00:00]可以发现一个简单的构造函数开发者心中默认一般都是本地时间然而它却允许直接创建出一个既非本地时间、也非UTC时间的怪物。当d3转成本地时间时会把d3作为UTC时间来加8小时。当d3转成UTC时间时却会把d3作为本地时间来减8小时。那么d3到底是本地时间还是UTC时间呢没人清楚除非它存在于一个非常小的局部作用域中并且生命周期极短这时候我们也许可以假设它为本地时间。然而这个本地时间也依赖于它的运行环境如果是有几台时区不一致的计算机阉割了时区信息的DateTime转成字符串在网络中传输到另一个时区比如隔壁的十一区的另一台服务器中解析出来后所谓的东八区本地时间8点到了日本变成了既非本地时间、也非UTC时间的怪物。DateTime在官方文档中已经不推荐使用而是推荐使用它的代替品DateTimeOffset后者保存时区信息。在交互模式中验证一下 var dto DateTimeOffset.Now; var dto2 dto.ToUniversalTime(); dto dto2true可以发现DateTimeoffset判断两个时间是否等价的标准是以世界时间轴的时刻来判断的与时区无关甚至可以与UTC时间无关。只要它们都在同一个时间体系里、能互相变换即可。在实际项目中建议大家如果有使用DateTime的统一换成DateTimeOffset。如果有用到32比特的UNIX时间戳的统一换成64比特的long来存储UtcTicks。即使项目本身不跨时区仍然有可能遇到时区问题比如如果使用了mongodb的mongodb存储的时候都是统一存成UTC时间的好像是忘了,而且一般来说会带有时区信息。但是有一种情况比较糟糕如果你的DateTime的Kind是Unspecified的隐含的时区的信息就会丢失。再取出来之后就会有8小时的时差。有一些第三方的或者自己公司的类库之类的如果没有处理好这个问题也有潜在的时区丢失问题。UNIX时间戳存成Utc Ticks也有好处无论是精度还是时间跨度都远超UNIX时间戳。只需要64比特即可获得下至100纳秒的精度上超万年的时间跨度一劳永逸无论是转回UNIX时间戳还是JS时间戳都能胜任。空间代价也非常小除非你的存储空间真的是硬伤。。原文https://www.cnblogs.com/zlmdy/p/8560396.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com