2013-10-13 17 views
5

Ho il seguente test che passa:MongoDB C# conducente e 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()); 
     } 
    } 
} 

Se io rimuovere il commento una delle Asserts.AreEqual ottengo un errore (commentata di seguito).

L'entità risparmiato è:

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

Capisco che questo potrebbe essere correlato a isodate e UTC (io sono in GMT + 1), ma ho un po 'infastidito dal fatto che le mie date sono salvati con una differenza giorno qualcosa nella raccolta e mi richiede di convertire in localTime in qualsiasi momento, recupero alcuni dati con le date.

Qual è la ragione di questo comportamento e c'è un modo per evitarlo?

risposta

8

Nella maggior parte dei casi si desidera memorizzare i tempi di data UTC del database in modo che il DateTime dovrebbe essere costruito come: -

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

Con questo il primo dei tuoi test di unità commentato ora passa.

Senza specificare il DateTimeKind si sta lasciando al caso. MongoDB sembra presupporre che sia locale e lo converte in UTC nel database.

Si noti inoltre che i valori DateTime di MongoDB hanno una precisione inferiore rispetto ai valori di DateTime di .NET. Se si desidera memorizzare valori DateTime arbitrari e recuperarli in modo che corrispondano ancora, sarà necessario arrotondarli al millisecondo più vicino prima di memorizzarli.

Se davvero si vuole memorizzare ore locali vi consiglio di passare DateTime-DateTimeOffset e serializzare come valore Tick lungo per l'UTC DateTime e un valore per l'offset.

Nota che se non si memorizza l'offset calcolato al momento il valore DateTime è stato ottenuto poi i metodi .NET per la conversione a LocalTime sono sostanzialmente inutile dal momento che non si sa quando l'ora legale ha iniziato, né si sa nemmeno cosa zona il valore DateTime proviene da. Nel complesso, la gestione di DateTime .NET lascia molto a desiderare e contiene molti metodi fuorvianti che pretendono di aiutare ma in realtà non lo fanno.

+0

Grazie! Il problema più grande è risolto. Ho provato il codice e anche se la prima e la seconda affermazione non sono ancora passando per la differenza di tempo 2 ore almeno ottengo lo stesso giorno ... Capisco .Net complica la gestione DateTime ma in questo caso sembra più un problema con il driver Mongodb. Per le operazioni CRUD di base, mi aspetto di ottenere ciò che ho inserito come in qualsiasi altra soluzione. In questo caso, desidero solo memorizzare le date (non c'è tempo) memorizzando le didascalie, a complicare la ricerca della raccolta direttamente nella shell di mogodb. – Ronnie

Problemi correlati