2013-10-13 3 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 в базе данных, чтобы ваш DateTime должен быть построен как: -

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

С этим первым из ваших комментировал модульных тестов в настоящее время проходит.

Не указывая DateTimeKind, вы оставляете его на волю случая. MongoDB полагает, что он локальный и преобразует его в UTC в базе данных.

Обратите также внимание, что значения MongoDB DateTime имеют меньшую точность, чем значения .NET DateTime. Если вы хотите сохранить произвольные значения DateTime и вернуть их таким образом, чтобы они по-прежнему совпадали, вам необходимо округлить их до ближайшей миллисекунды, прежде чем хранить их.

Если вы действительно хотите сохранить местное время, я рекомендую вам перейти от DateTime в DateTimeOffset и сериализовать его как длинное значение Tick для UTC DateTime и значение для смещения.

Обратите внимание, что если вы не храните смещение, вычисленное во время получения значения DateTime, методы .NET для преобразования в LocalTime практически бесполезны, поскольку они не знают, когда началось летнее время, и даже не знают, в какой зоне появляется значение DateTime. В целом, обработка .NET DateTime оставляет желать лучшего и содержит множество вводящих в заблуждение методов, которые утверждают, что помогают, но на самом деле этого не делают.

+0

Спасибо! Большая проблема решена. Я пробовал код, а также если первое и второе утверждение все еще не проходят за 2-часовую разницу во времени, по крайней мере, я получаю тот же день ... Я понимаю .Net усложняет обработку DateTime, но в этом случае кажется, что мне больше проблема с драйвером Mongodb. Для основных операций с CRUD я бы ожидал получить то, что я вставил, как в любом другом решении. В этом случае я хочу только хранить даты (нет времени), сохраняя тики, так как долго усложняет запрос коллекции непосредственно в оболочке mogodb. – Ronnie

Смежные вопросы