2

我和我的同事在辩论中陷入僵局,非常感谢其他人的意见。

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

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

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

我了解 Mongo 在内部将 DateTime 存储为 UTC 时间。我什至理解为什么当你调用它时它可能会返回 UTC。

这是辩论开始的地方。

有人建议这只是一个外观问题,仅在显示日期时出现问题。因此,我们应该在接口层中简单地调用 .ToLocalTime。我不同意并断言这危险地破坏了我们在实现服务定位器模式时创建的抽象层。它还提出了有关与这些日期时间的交互的问题,因为它与触发其他事件有关。

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

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

我对其他人对这个话题的看法很感兴趣。

预先感谢您的意见。

4

1 回答 1

8

你为什么不首先将UTC存储在数据库中?在大多数情况下,DateTime应该以 UTC 存储,因为它通常指的是一个时间点。这适用于任何在物理意义上指代时间的事物,以及任何假设时间是单调的、递增的和唯一的,但对于大多数当地时间来说,这些都不是真的。

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

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

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

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

于 2011-12-08T23:09:30.813 回答