2012-04-12 23 views
8

tengo un método que obtiene una propiedad de fecha de una fuente (ya sea un DataRow o una SqlDataReader):La conversión de DateTime a SqlDateTime es inexacta

protected SqlDateTime GetSqlDateTimePropertyValue(string propertyName, object source) 
{ 
    var objValue = GetPropertyValue(propertyName, source); 
    var value = objValue == DBNull.Value ? null : (DateTime?)objValue; 
    var sqlValue = new SqlDateTime(); 
    if (value.HasValue) sqlValue = value.Value; 
    return sqlValue; 
} 

pero la conversión parece estar cambiando ligeramente la fecha para que mi prueba siempre falla.

¿Alguien sabe por qué este método se convertiría incorrectamente?

Al final del procedimiento, parece que la conversión a SqlDateTime hace algo de redondeo:

value.Value.Ticks:  634698391707468296 
sqlValue.Value.Ticks:  634698391707470000 
+0

Ver: http://stackoverflow.com/questions/7824766/how-does-sqldatetime-do-its-precision-reduction –

Respuesta

9

Sí - el servidor SQL Server DATETIME tiene una precisión de 3.33ms - el tipo de datos .NET sin embargo puede representar solo milisegundos.

Por lo tanto, a veces tendrá algunos problemas de redondeo.

Leer mucho más acerca de la DATETIME tipo de datos y sus propiedades y peculiaridades aquí:

Demystifying the SQL Server DATETIME datatype

Además, SQL Server 2008 introdujo una serie de nuevos tipos de datos relacionados con la fecha - leer más acerca de los que están aquí:

SQL Server 2008 New DATETIME datatypes

Estos tipos hacen incluir un tipo de datos DATETIME2 que es exacta a 100 ns.

+1

Guau, respuesta rápida y excelente! Gracias! –

3

Se documenta la precisión de la fecha y hora de TSQL; consulte la sección titulada "Redondeo de la segunda precisión fraccional de fecha y hora" en this link from MSDN. Presupuesto de la sección:

valores de fecha y hora se redondean a incrementos de .000, .003, .007 o segundos, como se muestra en la siguiente tabla.

.NET date-time tiene mejor precisión.

Además, MS recomienda utilizar tipos de datos más nuevos (como datetime2, date, time, etc.) en lugar de fecha y hora. El tipo de datos datetime2 presentado con Sql Server 2008 tiene una precisión similar (100ns) (igual que la estructura de fecha/hora .NET) y también admite el formato de cadena ISO 8601 que haría más simple la conversión de .NET fecha/hora a SQL fecha-hora ((es decir, cuando se ven obligados a utilizar literales en lugar de consulta parametrizada) y sin pérdidas.

+0

Gracias vinayc! Creo que marc_s te pilló en la publicación . Excelente respuesta, aunque +1, y gracias –

0

el objeto SqlDateTime tiene menor precisión que el objeto .NET DateTime, y así al convertir a SQL que va a perder cierta precisión.

Cuestiones relacionadas