mbdavid / LiteDB

LiteDB - A .NET NoSQL Document Store in a single data file
http://www.litedb.org
MIT License
8.52k stars 1.24k forks source link

[BUG] BsonValue constructor for DateTime drops microseconds #2218

Closed gjvanvuuren closed 2 years ago

gjvanvuuren commented 2 years ago

Version 5.0.12

Describe the bug In the following constructor:

        public BsonValue(DateTime value)
        {
            this.Type = BsonType.DateTime;
            this.RawValue = value.Truncate();
        }

the Truncate() statement creates a new DateTime by using the Year, Month, Day, Hour, Minutes, Seconds, Milliseconds properties. This causes the microseconds and nanoseconds to be dropped.

Code to Reproduce

var dt = DateTime.Parse("2022-03-23T12:47:56.9748544+01:00");
var bval = new BsonValue(dt);
var wrongFormat = bval.AsDateTime.ToString("o");
var wrongTicks = dt.Ticks == bval.AsDateTime.Ticks;

Expected behavior The underlying structure of DateTime should not change, as reflected by the ticks, and/or the round-trip date/time pattern ("o").

Additional context Especially in the context of IOT devices, the accuracy provided by microseconds become important. The easiest solution to this problem would be to not create a new DateTime object in the constructor.

AntonIOIOIO commented 2 years ago

https://www.litedb.org/docs/data-structure/.

Following the BSON specification, DateTime values are stored only up to the miliseconds. All DateTime values are converted to UTC on storage and converted back to local time on retrieval.

gjvanvuuren commented 2 years ago

OK. Strange limitation, but OK. I see on other sites that the solution is: You need to store the date as a string in MongoDB if you want the full precision. I'll have to go with that.

AntonIOIOIO commented 2 years ago

You could store it as binary instead!