DateTimes and time zones are always fun...
The server does not do any conversion to UTC, it just stores whatever
value the client sends to it.
The C# driver converts all DateTimes to UTC before sending them to the
server. Whether it converts back to LocalTime or not when retrieving
the data is more complicated.
When using BsonDocuments:
A DateTime value passed to a BsonDateTime constructor is stored as-is
in the BsonDateTime in-memory object, it is not yet converted to UTC.
So if you call BsonDateTime.Value you will get back exactly the same
DateTime value you passed to the constructor. The conversion to UTC
happens when the value is sent to the server. When a BsonDateTime is
read back from the server it will always be in UTC.
When using POCOs:
You can provide some control over how DateTimes are serialized and
deserialized using this attribute:
[BsonDateTimeOptions(DateOnly = true|false, Kind = DateTimeKind.Utc|
Local|Unspecified, Representation = BsonType.DateTime|Document|Int64|
String)]
When DateOnly = true the driver enforces that the TimeOfDay component
be zero, and also doesn't convert to UTC so that the TimeOfDay
component will be zero on the server also.
When Kind = Utc, values returned from the server remain in UTC. When
Kind = Local or Unspecified, values returned from the server are
converted to LocalTime and the Kind property is set to Local or
Unspecified.
For representation stick to BsonType.DateTime, *unless* you need to
store .NET DateTimes *without* losing precision (the BSON DateTime
representation is only accurate to the millisecond). Document
representation stores the value twice, once as a BSON value (so you
can write queries against easily) and once as a 64 bit .NET Ticks
value. Int64 stores just the .NET Ticks value, and String stores the
DateTime as an ISO-8601 string.
My recommendations:
- always run servers set to the GMT time zone (not everyone does this)
- always use UTC in your data models and only convert to LocalTime
when displaying to the user
Also, keep in mind that "LocalTime" is based on the time zone setting
of the machine your code is running on. This is often the wrong
timezone anyway. Your code may be running on a server set to GMT. Or
your application may be used by users in multiple time zones and you
need to be multi time zone aware anyway.