我的同事和我在辩论中处于僵局,其他人的意见将不胜感激.
我们利用服务定位器模式和通用接口来抽象我们的所有数据访问,以便随着需求的变化,我们可以轻松地在不同的数据源之间进行交换.我们的调用代码没有指示数据的存储位置或方式.它只是通过服务注册表提供的服务访问数据.
当我们在对象上有DateTime字段并将其存储到MongoDB数据源时,我们正在讨论的问题就出现了.
我注意到的是,当我们在C#中有一个带有DateTime的对象时,它显示为正确的时间.当我们使用MongoVUE登录我们的MongoDB服务器来检查对象时,它会显示正确的时间.但是当我们检索对象时,DateTime现在是UTC.当将内存中的DateTime与从MongoDB数据源检索到的对象中的DateTime进行比较时,这显然会产生问题.
我知道Mongo在内部将DateTime存储为UTC时间.我甚至理解为什么它会在你打电话时返回UTC.
这是辩论开始的地方.
有人建议这只是一个美容问题,只是显示日期时的问题.因此,我们应该简单地在界面层中调用.ToLocalTime.我不同意并声称这危险地打破了我们在实现服务定位器模式时创建的抽象层.它还提出了与那些日期时间的交互问题,因为它涉及触发其他事件.
我所读到的其他地方是我们应该将我们的时间存储为字符串,特别是作为UTC格式的一些标准.以这种方式,接口层不知道或不关心DateTime的存储方式,也不知道我们的对象,因为每个数据源都以相同的方式存储该字符串.
我使用ISO 1806格式取得了成功,但我的同事认为这是一个"hacky"修复,并且使用.toLocalTime是处理这种情况的适当方法.
我对其他人对这个话题的看法很感兴趣.
提前感谢您的意见.
为什么不首先在数据库中存储UTC?在大多数情况下,DateTime
应该以UTC格式存储,因为它通常指的是某个时间点.对于任何涉及物理意义上的时间的东西都是如此,并且任何假设时间是单调的,增加的和独特的,在大多数当地时间都不是真的.
偶尔使用当地时间确实有意义:假设公共汽车每天早上9点离开.这意味着两个连续事件之间24小时通过.但是,如果时区有DST,则每年一次为23小时,间隔为25小时.
但是,如果你需要争论这种数据,那么简单DateTime
就不行了; DST规则可以更改,时区可以更改等.在C#中,即使日期为"历史" ,将应用的DST规则是当前有效的规则.因此,具有历史日期的日期算术可能会造成严重破坏.如果你真的需要解决这个问题,最起码,你应该保存它时区的时间为(不仅仅是抵消,甚至只是一个isLocal
标志).
在数据库中存储可以存储为二进制文件的文本信息对我来说似乎不太优雅,也没有改变某些中间层的值.前者效率低,并且受到前面提到的当地时间的特殊性的影响,后者只有第二个问题.
顺便说一句,要完成后者,你可以用[BsonDateTimeOptions(Kind=DateTimeKind.Local)]
它来装饰属性,它会为你做转换,但当然也会遇到同样的问题.