Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BSON serializer not handling DateTimeOffsets properly #898

Closed
remids opened this issue Apr 29, 2016 · 2 comments
Closed

BSON serializer not handling DateTimeOffsets properly #898

remids opened this issue Apr 29, 2016 · 2 comments

Comments

@remids
Copy link

remids commented Apr 29, 2016

It appears that BSON serialization deserializes DateTimeOffset instances as DateTime instances. I looked into it, and there does not appear to be any tests using DateTimeOfset in BsonReaderTests.cs.

Used the following to determine what's currently written out:

MemoryStream ms = new MemoryStream();
BsonWriter writer = new BsonWriter(ms);
writer.WriteStartArray();
writer.WriteValue(new DateTimeOffset(2000, 12, 29, 12, 30, 0, new TimeSpan(-5, 0, 0)));
writer.WriteEnd();
string bson = BytesToHex(ms.ToArray());

This gave me the following strings, for testing the reader:

Offset of 00:00: "10-00-00-00-09-30-00-40-C5-E2-BA-E3-00-00-00-00"
Offset of 05:00: "10-00-00-00-09-30-00-C0-1C-D0-B9-E3-00-00-00-00"
Offset of -05:00: "10-00-00-00-09-30-00-C0-6D-F5-BB-E3-00-00-00-00"

Using the existing BSON tests as a guide, I then tried this:

[Test]
public void ReadDateTimeOffset()
{
    // In all cases, looking at 2000-12-29 12:30:00 but with differing offset
    var dt = new DateTimeOffset(2000, 12, 29, 12, 30, 0, TimeSpan.Zero);
    byte[] data = HexToBytes("10-00-00-00-09-30-00-40-C5-E2-BA-E3-00-00-00-00"); // Timespan +00:00
    //byte[] data = HexToBytes("10-00-00-00-09-30-00-C0-1C-D0-B9-E3-00-00-00-00"); // Timespan +05:00
    //byte[] data = HexToBytes("10-00-00-00-09-30-00-C0-6D-F5-BB-E3-00-00-00-00"); // Timespan -05:00

    MemoryStream ms = new MemoryStream(data);
    BsonReader reader = new BsonReader(ms);
#pragma warning disable 612, 618
    reader.JsonNet35BinaryCompatibility = true;
#pragma warning restore 612, 618
    reader.ReadRootValueAsArray = true;
    reader.DateTimeKindHandling = DateTimeKind.Utc;

    Assert.IsTrue(reader.Read());
    Assert.AreEqual(JsonToken.StartArray, reader.TokenType);

    Assert.IsTrue(reader.Read());
    Assert.AreEqual(JsonToken.Date, reader.TokenType);
    Assert.AreEqual(dt, reader.Value);
    Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType);

    Assert.IsTrue(reader.Read());
    Assert.AreEqual(JsonToken.EndArray, reader.TokenType);

    Assert.IsFalse(reader.Read());
    Assert.AreEqual(JsonToken.None, reader.TokenType);
}

The Assert comparing the value fails, it has a DateTime - not a DateTimeOffset:

Test 'Newtonsoft.Json.Tests.Bson.BsonReaderTests.ReadDateTimeOffset' failed:
Expected: 12/29/2000 12:30:00 +00:00
But was: 2000-12-29 12:30:00.000

This is also confirmed by reader.ValueType, which is System.DateTime.

I was originally trying to get to the bottom of this:
https://stackoverflow.com/questions/36944671/json-net-bson-serialization-incorrectly-handling-datetimeoffset

It works fine de/serializing to JSON; it's just BSON that appears to be a problem.

@JamesNK
Copy link
Owner

JamesNK commented May 1, 2016

The BSON spec doesn't support dates with timezones - just UTC ticks. It's a known limitation.

@JamesNK JamesNK closed this as completed May 1, 2016
@remids
Copy link
Author

remids commented May 2, 2016

Apologies, I didn't realize and hadn't thought to look at the spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants