2011-05-17 26 views
12

Tengo un problema con guardar y recuperar fechas con Mongo usando el controlador C#. Por alguna razón, está truncando los tics.Problemas de fecha y hora con Mongo y C#

Cuando almaceno esto:

DateTime -> 5/17/2011 7:59:13 PM 
Ticks -> 634412591533741650 

consigo este regreso:

DateTime -> 5/17/2011 7:59:13 PM 
Ticks -> 634412591533740000 

Así que si trato de hacer:

serverDateTime == mongoDateTime 

Siempre falla. De todos modos alrededor de esto?

+2

Si no se preocupan por milisegundos precistion en su comparación, en lugar de 'serverDateTime == mongoDateTime' que podría hacer' Math.abs ((serverDateTime - mongoDateTime) .TotalMilliseconds <1000' –

+0

Eso es lo suficientemente bueno, pero demasiado prolijo tener que hacer en todas partes. Supongo que podría hacerlo como un método de extensión. ¿Alguna idea de por qué ocurre eso? – Micah

+0

@Bala R 1 tick = 1 diez-millonésima de segundo, así que creo que quieres decir si * todo * te importa aproximadamente es milisegundos. Por ejemplo 'Math.Abs ​​((serverDateTime - mongoDateTime) .TotalMilliseconds) <1 '. –

Respuesta

10

La razón es que las tiendas de formato BSON DateTime valores con menor precisión que un valor .NET DateTime, por lo que cuando se lee de nuevo de la base de datos el valor ha sido truncado

Si su valor DateTime es una propiedad de una clase C# que está serializando le puede pedir al serializador para serializar el valor de fecha y hora como un documento incrustado que contiene tanto el valor BSON DateTime (truncado) y el valor original .NET DateTime (almacenado como Ticks). En ese caso, el valor no se truncará cuando se deserialice.

Por ejemplo:

public class MyClass { 
    public ObjectId Id; 
    [BsonRepresentation(BsonType.Document)] 
    public DateTime MyDateTime; 
} 

También puede utilizar un BsonRepresentation de Int64 o cadena y no perder precisión, pero luego el documento almacenado única ha garrapatas o una representación de cadena y sin BSON DateTime, lo que hace es difícil hacer consultas relacionadas con DateTime.

También querrá tener en cuenta que los valores de DateTime se almacenan en UTC en la base de datos. La mejor práctica es usar siempre los valores UTC para el almacenamiento y solo usar las horas locales cuando se muestren al usuario.

+0

Gracias por la sugerencia. Voy a almacenarlo como fecha y hora, pero utilizo el método de extensión de @Bala R para comparar. – Micah

+2

Este uso de atributo arroja la excepción "Un atributo de opciones de serialización de tipo BsonRepresentationAttribute no se puede aplicar ..." para mí, pero '[BsonDateTimeOptions (Representation = BsonType.Document)]' funciona bien – YMC

3

Aquí es una extensión que podría utilizar :)

public static class MongoDateComparison 
{ 
    private static int precisionInMilliseconds = 1000; 
    public static bool MongoEquals(this DateTime dateTime, DateTime mongoDateTime) 
    { 
     return Math.Abs((dateTime - mongoDateTime).TotalMilliseconds) < precisionInMilliseconds; 
    } 
}