处理与服务定位器模式一起使用时MongoDB如何存储DateTime [英] Dealing with how MongoDB stores DateTime when used with Service Locator Pattern

查看:187
本文介绍了处理与服务定位器模式一起使用时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格式存储,因为它通常指的是某个时间点。对于任何涉及物理意义上的时间的东西都是如此,并且任何假设时间是单调的,增加的和独特的,在大多数当地时间都不是真的。



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



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



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



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


My colleague and I are at an impasse in a debate and other's input would be greatly appreciated.

We utilize the Service Locator Pattern and a common interface to abstract all of our data access so we can easily swap between different data sources as our needs change. Our calling code has no indication of where the data is being stored or how. It simply accesses the data via the service it is fed from the service registry.

The issue we are debating occurs when we have DateTime fields on an object and store it to a MongoDB datasource.

What I have noticed is that when we have an object in C# with a DateTime it appears as the correct time. When we log into our MongoDB server with MongoVUE to inspect the object it shows the correct time. But when we retrieve the object the DateTime is now in UTC. This obviously creates issues when comparing a DateTime in memory to one in an object that has been retrieved from the MongoDB data source.

I understand that Mongo stores DateTime internally as UTC time. I even understand why it might be returning UTC when you call it.

Here is where the debate begins.

It's been suggested that this is simply a cosmetic issue and only a problem when displaying dates. Thus we should simply call .ToLocalTime within the interface layer. I disagree and assert that this dangerously breaks the layers of abstraction we have created in implementing the Service Locator Pattern. It also raises questions regarding interaction with those date times as it pertains to triggering other events.

What I have read else where is that we should be storing our times as string, specifically as some standard of UTC format. In this manner the interface layer doesn't know or care how the DateTime is stored and neither does our object since every data source would store that string in the same manner.

I've had success with doing this using the ISO 1806 format but my colleague feels this is a 'hacky' fix and that using the .toLocalTime is the appropriate way to deal with this situation.

I am interested in what others have to say on the topic.

Thank you in advance for your input.

解决方案

Why aren't you storing UTC in the DB in the first place? In most cases, DateTime should be stored in UTC, because it usually refers to a point in time. This is true for anything that refers to time in a physical sense, and anything that assumes that time is monotonic, increasing and unique, none of which are true for most local times.

Occasionally, using local times does make sense: suppose a bus leaves every day at 9am. This means that 24 hours pass between two consecutive events. However, if the time zone has a DST, it will be a 23h, respectively 25h interval once a year.

However, if you need to wrangle this kind of data, a simple DateTime doesn't do the trick; DST rules can change, timezones can change, etc. In C#, the DST rules that will be applied are the ones that are currently valid, even if the date is 'historic'. Date arithmetic with historic dates can thus wreak havoc. If you really need to cope with this, at the very least, you should store which timezone the time is in (not only the offset, or even just a isLocal flag).

Storing textual information in the database that can be stored binary doesn't seem very elegant to me, neither does changing the value in some middle layer. The former is inefficient and suffers from the previously mentioned peculiarities of local time, the latter only has the 2nd problem.

BTW, to accomplish the latter, you could decorate the property with [BsonDateTimeOptions(Kind=DateTimeKind.Local)], which will do the conversion for you, but suffers from the same problems, of course.

这篇关于处理与服务定位器模式一起使用时MongoDB如何存储DateTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆