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

时间:2011-12-08 21:53:48

标签: c# mongodb interface mongodb-.net-driver service-locator

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

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

当我们在对象上有DateTime字段并将其存储到MongoDB数据源时,就会出现我们正在讨论的问题。

我注意到当我们在C#中有一个带有DateTime的对象时,它显示为正确的时间。当我们使用MongoVUE登录我们的MongoDB服务器来检查对象时,它会显示正确的时间。但是当我们检索对象时,DateTime现在是UTC。当将内存中的DateTime与从MongoDB数据源检索到的对象中的DateTime进行比较时,这显然会产生问题。

据我所知,Mongo在内部将DateTime存储为UTC时间。我甚至理解为什么在你打电话时它可能会返回UTC。

这是争论开始的地方。

有人建议这只是一个整容问题,只是在显示日期时出现问题。因此,我们应该简单地在界面层中调用.ToLocalTime。我不同意并声称这危险地打破了我们在实现服务定位器模式时创建的抽象层。它还引发了与那些日期时间的交互问题,因为它涉及触发其他事件。

我所读到的其他地方我们应该将我们的时间存储为字符串,特别是作为UTC格式的一些标准。以这种方式,接口层不知道或不关心DateTime的存储方式,也不知道我们的对象,因为每个数据源都以相同的方式存储该字符串。

我使用ISO 1806格式取得了成功,但我的同事认为这是一个“hacky”修复,并且使用.toLocalTime是处理这种情况的适当方法。

我对其他人对此主题的看法感兴趣。

提前感谢您的意见。

1 个答案:

答案 0 :(得分:8)

为什么不首先将UTC存储在数据库中?在大多数情况下,DateTime应该以UTC格式存储,因为它通常指的是某个时间点。对于任何涉及物理意义上的时间的东西都是如此,任何假设时间都是单调的,增加的和独特的东西,在大多数当地时间都不是真的。

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

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

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

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