Dealing with how MongoDB stores DateTime when used with Service Locator Pattern

孤街浪徒 提交于 2019-12-02 04:26:58

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/8438219/dealing-with-how-mongodb-stores-datetime-when-used-with-service-locator-pattern

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!