Storing Utc and Local datetime in Mongo Storing Utc and Local datetime in Mongo mongodb mongodb

Storing Utc and Local datetime in Mongo


This is the way I force MongoDB to store the raw value, and ignore the DateTimeKind attribute in DateTime object.

This may not apply to your business logic, but make sense for us for our particular reasons.

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);    }}


New version of 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);    }}


In .net driver version 2.4, use this:

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

This way datetime values will be stored with kind=utc in db, but deserialized in local kind.