MongoDB, C# and DateTimeOffset

MongoDB, C# and DateTimeOffset

The MongoDB driver for C#/.NET can currently be serialized/deserialized in three different ways - as an array, object or string.

You can control the BSON representation of your property by adding the [BsonRepresentation] attribute or set it on your class map.

[BsonRepresentation(BsonType.String)]
public DateTimeOffset EventStart { get; set; }

As mentioned the DateTimeOffsetSerializer supports three different representation types:

  • BsonType.Array (default)
  • BsonType.Document
  • BsonType.String

Array representation (default)

By default DateTimeOffset is serialized as an array consisting of the ticks and the offset in minutes.

// Serialization code for BsonType.Array
bsonWriter.WriteStartArray();
bsonWriter.WriteInt64(value.Ticks);
bsonWriter.WriteInt32((int)value.Offset.TotalMinutes);
bsonWriter.WriteEndArray();

// Example JSON output
// [NumberLong("636415154304356493"), 120]

This is probably the reason you are here right now. This is different than DateTime which is stored as a BSON date (ISODate("2017-09-20T12:46:53.552Z")) and it makes it harder to query manually and harder to read.

I'm sure there's a good reason why this was made the default, but I'm not exactly sure why.

String representation

The string representation is more recognizable to most people and probably what you are looking for.

// Serialization code for BsonType.String
bsonWriter.WriteString(JsonConvert.ToString(value));

// Example JSON output
// "2017-09-20T14:47:37.8324739+02:00"

Document representation

The last of the three options is the document representation, which is more or less a combination of the array and string representation combined in an object (document).

// Serialization code for BsonType.Document
bsonWriter.WriteStartDocument();
bsonWriter.WriteDateTime("DateTime", BsonUtils.ToMillisecondsSinceEpoch(value.UtcDateTime));
bsonWriter.WriteInt64("Ticks", value.Ticks);
bsonWriter.WriteInt32("Offset", (int)value.Offset.TotalMinutes);
bsonWriter.WriteEndDocument();

// Example JSON output
// {
//     "DateTime": ISODate("2017-09-20T12:56:06.642Z"),
//     "Ticks": NumberLong("636415161666429142"),
//     "Offset": 120
// }