Mongodb c#驱动程序和ISODate

Mongodb c#驱动程序和ISODate,c#,mongodb,C#,Mongodb,我通过了以下测试: namespace MongoDateTest { [TestFixture] public class DateTesting { public class TestEntity { public string Id { get; set; } public string StringTest { get; set; } public DateT

我通过了以下测试:

namespace MongoDateTest
{

    [TestFixture]
    public class DateTesting
    {
        public class TestEntity
        {
            public string Id { get; set; }
            public string StringTest { get; set; }
            public DateTime DateTest { get; set; }

        }
        [Test]
        public void MongoDateConversion()
        {
            const string connectionString = "mongodb://localhost";
            var client = new MongoClient(connectionString);
            var server = client.GetServer();
            var database = server.GetDatabase("test");
            var collection = database.GetCollection<TestEntity>("entities");
            var entity = new TestEntity { 
                   Id = "1", 
                   StringTest = "Test",
                   DateTest = new DateTime(2013, 10, 13) //this is the date
            };
            collection.Save(entity);
            var id = entity.Id;
            var query = Query<TestEntity>.EQ(e => e.Id, id);
            var entityNew = collection.FindOne(query);
            Assert.AreEqual(entityNew.Id, entity.Id);
            Assert.AreEqual(entity.StringTest, entityNew.StringTest);

            //Assert.AreEqual(entity.DateTest,entityNew.DateTest);
            // This gives one day error:
            //  Expected: 2013-10-13 00:00:00.000
            //  But was:  2013-10-12 22:00:00.000
            //Assert.AreEqual(entity.DateTest.ToLocalTime(),entityNew.DateTest.ToLocalTime());
            // This gives a 2 hours error.
            //   Expected: 2013-10-13 02:00:00.000
            //   But was:  2013-10-13 00:00:00.000
            Assert.AreEqual(entity.DateTest, entityNew.DateTest.ToLocalTime());
        }
    }
 }
我知道这可能与ISODate和UTC有关(我在UTC+1中),但我有点恼火,因为我的日期在集合中以一天的差异保存,并要求我在任何时候获取带有日期的数据时转换为localTime


这种行为的原因是什么?有没有办法避免这种情况?

在大多数情况下,您希望在数据库中存储UTC日期时间,因此您的日期时间应构造为:-

DateTest = new DateTime(2013, 10, 13, 0, 0, 0, DateTimeKind.Utc) //this is the date
这样,您的第一个注释单元测试现在就通过了

如果不指定
DateTimeKind
,您将把它留给偶然。MongoDB似乎假定它是本地的,并在数据库中将其转换为UTC

还请注意,MongoDB日期时间值的精度低于.NET日期时间值。如果您想存储任意的日期时间值,并以它们仍然匹配的方式将其恢复,则需要在存储它们之前将它们四舍五入到最接近的毫秒

如果确实要存储本地时间,我建议您从
DateTime
切换到
DateTimeOffset
,并将其序列化为UTC日期时间的长刻度值和偏移值


请注意,除非存储在获取日期时间值时计算的偏移量,否则转换为LocalTime的.NET方法基本上是无用的,因为它们不知道夏令时何时开始,甚至不知道日期时间值来自哪个区域。总的来说,.NET DateTime处理还有很多需要改进的地方,其中包含许多误导性的方法,这些方法声称有帮助,但实际上没有帮助。

您也可以在模型中这样做。 公共类测试

{
    public string Id { get; set; }

    public string StringTest { get; set; }

    [BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
    public DateTime DateTest { get; set; }
}

谢谢更大的问题解决了。我尝试了代码,而且如果第一个和第二个断言在2小时的时差内仍然没有通过,至少我在同一天得到了。。。我理解.Net使日期时间处理复杂化,但在我看来,这更像是Mongodb驱动程序的问题。对于基本CRUD操作,我希望得到我在任何其他解决方案中插入的内容。在这种情况下,我只希望存储日期(没有时间)来存储刻度,因为直接在mogodb shell中查询集合会很复杂。这对我来说可以正确保存UTC日期。执行查询时,[BsonDateTimeOptions(Kind=DateTimeKind.Local)]有助于将utc日期转换为本地时间。不需要额外的代码。
{
    public string Id { get; set; }

    public string StringTest { get; set; }

    [BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
    public DateTime DateTest { get; set; }
}