2013-10-13 168 views
5

我有以下測試通過:MongoDB的C#驅動程序和ISODate

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()); 
     } 
    } 
} 

如果我取消任何Asserts.AreEqual我得到一個錯誤(以下注釋)。

保存的實體是:

{ 
"_id" : "1", 
"StringTest" : "Test", 
"DateTest" : ISODate("2013-10-12T22:00:00Z") 
} 

我明白,這可能是一些涉及到ISODate和UTC(我在UTC + 1),但我有點惱火,我的日期將被保存爲一天的差異在集合中,並且需要我在任何時候使用日期獲取一些數據時將其轉換爲localTime。

這種行爲的原因是什麼,有沒有辦法避免它?

回答

8

在大多數情況下,你想存儲UTC日期時間在數據庫中,以便您的日期時間應該被解釋爲: -

DateTest = new DateTime(2013, 10, 13, 0, 0, 0, DateTimeKind.Utc) //this is the date 

有了這個第一的你評論的單元測試,現在通過。

如果沒有指定DateTimeKind,那麼您就有機會了。 MongoDB似乎認爲它是本地的,並將其轉換爲數據庫中的UTC。

另請注意,MongoDB DateTime值的精度低於.NET DateTime值。如果你想存儲任意的日期時間值並且以它們仍然匹配的方式取回它們,那麼在存儲它們之前,你需要將它們四捨五入到最接近的毫秒。

如果您確實想要存儲當地時間,我建議您從DateTime切換到DateTimeOffset,並將其序列化爲UTC日期時間的長Tick值和偏移值。

請注意,除非您存儲獲取DateTime值時計算的偏移量,否則轉換爲LocalTime的.NET方法本質上是無用的,因爲他們不知道夏令時何時開始,也不知道什麼區域DateTime值來自。總的來說,.NET DateTime處理留下了很多不足,並且包含很多聲稱幫助但實際上不會的誤導方法。

+0

謝謝!更大的問題解決了。 我試過代碼,如果第一個和第二個斷言仍然沒有通過2小時的時間差異,至少我得到同一天... 我明白.Net使DateTime處理複雜化,但在這種情況下,它似乎我更多的是一個Mongodb驅動程序問題。 對於基本的CRUD操作,我希望得到我插入的任何其他解決方案。 在這種情況下,我只需要存儲日期(無時間),直到在mogodb shell中直接查詢集合變得複雜。 – Ronnie