处理与服务定位器模式一起使用时MongoDB如何存储DateTime

我的同事和我在辩论中处于僵局,其他人的意见将不胜感激。

我们利用服务定位器模式和通用接口来抽象我们的所有数据访问,以便随着需求的变化,我们可以轻松地在不同的数据源之间进行交换。 我们的调用代码没有指示数据的存储位置或方式。 它只是通过服务注册表提供的服务访问数据。

当我们在对象上有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 DateTime存储,因为它通常指的是某个时间点。 对于任何涉及物理意义上的时间的东西都是如此,并且任何假设时间都是单调的,增加的和独特的东西,在大多数当地时间都不是这样。

偶尔,使用当地时间确实有意义:假设公共汽车每天早上9点离开。 这意味着两个连续事件之间24小时通过。 但是,如果时区有DST,则每年一次为23小时,间隔为25小时。

但是,如果你需要纠缠这种数据,那么简单的DateTime就不会这么做了。 DST规则可以更改,时区可以更改等。在C#中,即使日期为“历史”,将应用的DST规则是当前有效的规则。 因此,具有历史日期的日期算术可能会造成严重破坏。 如果你真的需要应付这个,至少,你应该存储时间的时区(不仅是偏移,甚至只是一个isLocal标志)。

在数据库中存储可以存储为二进制文件的文本信息对我来说似乎不太优雅,也没有改变某些中间层的值。 前者效率低, 并且受到前面提到的当地时间的特殊性的影响,后者只有第二个问题。

顺便说一句,要完成后者,你可以用[BsonDateTimeOptions(Kind=DateTimeKind.Local)]装饰属性,它将为你做转换,但当然也会遇到同样的问题。