2011-10-19 25 views
29

que tienen una fecha y hora que genero como esto:milisegundos en mis cambios DateTime cuando almacenados en SQL Server

DateTime myDateTime = DateTime.Now; 

entonces yo lo almacenan en la base de datos (en una columna mecanografiada DateTime) con Entity Framework. Luego lo recupero con OData (WCF Data Services).

Cuando se va en el valor TimeOfDay es: 09: 30: 03,0196095

Cuando sale el valor TimeOfDay es: 09: 30: 03,0200000

El efecto neto de esto hace de modo que los Milisegundos se vean como 19 antes de que se guarden y 20 después de que se vuelvan a cargar.

Así que cuando hago una comparación más adelante en mi código, falla donde debería ser igual.

¿SQL Server no tiene tanta precisión como .NET? ¿O es Entity Framework u OData lo que está estropeando esto?

Voy a truncar los milisegundos (realmente no los necesito). Pero me gustaría saber por qué está pasando esto.

+0

¿cómo estás haciendo la comparación? – ChrisBint

+1

Es una precisión diferente. Vea las preguntas relacionadas al lado. –

+1

¿En qué versión de SQL Server estás? Si 2008 'datetime2' tiene una mayor precisión. –

Respuesta

37

Esto realmente depende de la versión del servidor SQL que esté utilizando.

La resolución del campo de fecha y hora es de 3 posiciones decimales: por ejemplo: 2011-06-06 23:59:59.997 y solo se precisa dentro de 3,33 ms.

En su caso, 09: 30: 03,0196095 se está redondeado hasta 09: 30: 03,020 en el almacenamiento.

A partir de SQL 2008, se agregaron otros tipos de datos para proporcionar más detalles, como datetime2, que tiene hasta 7 lugares decimales y tiene una precisión de 100ns.

Véase lo siguiente para más información: http://www.karaszi.com/SQLServer/info_datetime.asp

creo que la mejor opción es proporcionar el redondeo al segundo antes de almacenar en el servidor SQL si los milisegundos es poco importante.

3

La precisión de DateTime en SQL Server es de milisegundos (.fff). Entonces 0.0196 redondearía a 0.020. Si puede usar datetime2, obtendrá una mayor precisión.

+0

Desafortunadamente, Date Data no es compatible con OData. Entonces no puedo usarlo – Vaccano

17

Esto se debe a la precisión del tipo SQL datetime. De acuerdo con MSDN:

los valores de fecha y hora se redondean en incrementos de 0.000, .003, .007 segundos o

Mira el Redondeo de fecha y hora fraccional Segunda precisión sección del this msdn page y' Entiendo cómo se completa el redondeo.

Como se indica por los demás, puede utilizar datetime2 en lugar de datetime para tener una mejor precisión:

  • datetime rango de tiempo es 00:00:00 through 23:59:59.997
  • datetime2 rango de tiempo es 00:00:00 through 23:59:59.9999999
+0

datetime2 todavía redondea milisegundos decimales de la misma manera para mí. ¿¿por qué?? – RobPio

2

Para quienes no tiene la capacidad de usar DateTime2 en SQL (por ejemplo: me gusta usar tablas generadas por un sistema separado que sería costoso e para cambiar para este único problema), hay una simple modificación de código que hará el redondeo por usted.

Referencia System.Data e importe el espacio de nombre System.Data.SqlTypes. A continuación, puede utilizar la estructura SqlDateTime para hacer la conversión para usted:

DateTime someDate = new SqlDateTime(DateTime.Now).Value; 

Esto convertirá el valor en garrapatas SQL, y luego de nuevo en .NET garrapatas, incluyendo la pérdida de precisión. :)

Una palabra de advertencia, este perderá la Kind de la estructura original DateTime (es decir Utc, Local). Esta conversión tampoco es simplemente redondear, hay una conversión completa que incluye cálculos de ticks, MaxTime cambios, etc. Por lo tanto, no use esto si se basa en indicadores específicos en DateTime ya que podrían perderse.

Cuestiones relacionadas