由于MongoDb存储时间按照UTC时间存储的,其官方驱动MongoDB.driver存储时间的时候将本地时间转换为了utc时间,但它有个蛋疼的bug,读取的时候非常蛋疼的是返回的是utc使时间。一个非常直观的体现是时间类型字段存储后和再读入的是不一致的,一个简单的示例如下:
table.InsertOne(new MyClass() { Time = DateTime.Now, }); foreach (var data in table.Find(_=> true).ToList()) { Console.WriteLine(data.Time); }
运行这段代码就会发现时间读取出来和写入的相差8个小时(北京时间)。
本身MongoDB官方是知道这个的,也有很多人反应的这一问题:DateTime timezone problem。,但官方是没有修改的意向的,官方给出的修改方法是: 在时间类型属性字段上显式标注是否为本地时间
[BsonDateTimeOptions(Kind = DateTimeKind.Local)] public DateTime SomeDateProperty {get;set;}
这个方法虽然看起来没有什么问题,但用起来麻烦不已,一来要在一些不相关的DTO库中引入Bson的库,另一方面加标记很容易遗漏。实际上操作起来是很不方便的。
于是,有人有找到了另一种方法,那就是全局设置时间序列化的方式:
DateTimeSerializationOptions.Defaults = DateTimeSerializationOptions.LocalInstance;
这个方法只在MongoDb.Driver 1.x版本中有效,到了2.x后,DateTimeSerializationOptions已经被废弃了,可以使用如下方法:
var serializer = new DateTimeSerializer(DateTimeKind.Local, BsonType.DateTime); BsonSerializer.RegisterSerializer(typeof(DateTime), serializer);
参考文章:
- How to save date properly?
- What is new way of setting DateTimeSerializationOptions.Defaults in mongodb c# driver?