在Mongo中存储Utc和本地日期时间

我有一个Mongo C#实现,它将datetime存储为UTC。

MongoDB.Bson.Serialization.Options.DateTimeSerializationOptions options = MongoDB.Bson.Serialization.Options.DateTimeSerializationOptions.UtcInstance; var serializer = new MongoDB.Bson.Serialization.Serializers.DateTimeSerializer(options); MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer( typeof(DateTime), serializer); 

我还需要将用户本地时区与UTC一起存储。 为了解释,我有两个属性

 DateTime WorkItemToCompleteBy{get; set;} [BsonDateTimeOptions(Kind = DateTimeKind.Unspecified)] DateTime WorkItemToCompleteByLocal{get; set;} 

我想将澳大利亚/美国/印度/其他时间存储在本地属性中,并将相应的UTC值存储在另一个属性中。 由于处理了几十个时区,我有代码将UTC转换为所需的时区并将其存储在WorkItemToCompleteByLocal属性中。 我希望Mongo按原样存储这个值并将其返回给我。 问题是Mongo总是将它存储为ISODate并将值转换为Utc版本。 解释。 如果UTC是0730小时,我计算布里斯class时间为1730小时并将其设置为WorkitemToCompleteByLocal,它们将保存为

 "WorkItemToCompleteBy" : ISODate("2013-06-05T07:30:00Z"), "WorkItemToCompleteByLocal" : ISODate("2013-06-05T12:00:00Z"), 

Mongo将提供的时间解释为本地, 服务器位于印度,并将其转换为相当于1200小时的UTC。 虽然它将值恢复为1730(IST虽然)但它违背了我的目的并阻止我在Mongo上运行任何基于本地时间的查询。 没有想法。 感谢任何帮助,以帮助存储WorkItemToCompleteByLocal日期’原样’而无需修改

新版C#driver =>

  public class MyMongoDBDateTimeSerializer : DateTimeSerializer { // MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic // We overwrite it to be DateTimeKind.Unspecified public override DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { var obj = base.Deserialize(context, args); return new DateTime(obj.Ticks, DateTimeKind.Unspecified); } // MongoDB stores all datetime as Utc, any datetime value DateTimeKind is not DateTimeKind.Utc, will be converted to Utc first // We overwrite it to be DateTimeKind.Utc, becasue we want to preserve the raw value public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value) { var utcValue = new DateTime(value.Ticks, DateTimeKind.Utc); base.Serialize(context, args, utcValue); } } 

这是我强制MongoDB存储原始值的方法,并忽略DateTime对象中的DateTimeKind属性。

这可能不适用于您的业务逻辑,但出于特殊原因对我们有意义。

 BsonSerializer.RegisterSerializer(typeof(DateTime), new MyMongoDBDateTimeSerializer()); public class MyMongoDBDateTimeSerializer : DateTimeSerializer { // MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic // We overwrite it to be DateTimeKind.Unspecified public override object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, System.Type nominalType, MongoDB.Bson.Serialization.IBsonSerializationOptions options) { var obj = base.Deserialize(bsonReader, nominalType, options); var dt = (DateTime) obj; return new DateTime(dt.Ticks, DateTimeKind.Unspecified); } // MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic // We overwrite it to be DateTimeKind.Unspecified public override object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, Type actualType, MongoDB.Bson.Serialization.IBsonSerializationOptions options) { var obj = base.Deserialize(bsonReader, nominalType, actualType, options); var dt = (DateTime)obj; return new DateTime(dt.Ticks, DateTimeKind.Unspecified); } // MongoDB stores all datetime as Utc, any datetime value DateTimeKind is not DateTimeKind.Utc, will be converted to Utc first // We overwrite it to be DateTimeKind.Utc, becasue we want to preserve the raw value public override void Serialize(MongoDB.Bson.IO.BsonWriter bsonWriter, System.Type nominalType, object value, MongoDB.Bson.Serialization.IBsonSerializationOptions options) { var dt = (DateTime) value; var utcValue = new DateTime(dt.Ticks, DateTimeKind.Utc); base.Serialize(bsonWriter, nominalType, utcValue, options); } } 

在.net驱动程序版本2.4中,使用此:

 using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Serializers; BsonSerializer.RegisterSerializer(DateTimeSerializer.LocalInstance); 

这样,datetime值将以db中的kind = utc存储,但以本地类型反序列化。