La documentación de MSDN para datetime recomienda usar datetime2 . Aquí está su recomendación:
Utilice los time
, date
, datetime2
y
datetimeoffset
los tipos de datos para un nuevo trabajo. Estos tipos se alinean con el estándar SQL. Son más portables.
time
, datetime2
y datetimeoffset
proporciona más segundos de precisión.
datetimeoffset
proporciona soporte de zona horaria para aplicaciones implementadas globalmente.
datetime2 tiene un rango de fechas más grande, una precisión fraccional predeterminada más grande y una precisión opcional especificada por el usuario. Además, dependiendo de la precisión especificada por el usuario, puede usar menos almacenamiento.
DateTime2
tipo (o cualquier otro SQL Server tipo para el caso) Ver los Contras en mi 10.07.17 respuesta por debajo de eso que estoy pidiendo?.DATETIME2
tiene un rango de fechas de "0001/01/01" a "DATETIME
9999/12/31 ", mientras que el tipo solo admite el año 1753-9999.Además, si lo necesita,
DATETIME2
puede ser más preciso en términos de tiempo; DATETIME está limitado a 3 1/3 milisegundos, mientras queDATETIME2
puede ser preciso hasta 100ns.Ambos tipos se asignan a
System.DateTime
.NET, no hay diferencia allí.Si tiene la opción, le recomendaría usar
DATETIME2
siempre que sea posible. No veo ningún beneficio al usarDATETIME
(excepto la compatibilidad con versiones anteriores): tendrá menos problemas (con fechas fuera de rango y problemas como ese).Además: si solo necesita la fecha (sin parte de tiempo), use DATE, ¡es tan bueno como
DATETIME2
y también le ahorra espacio! :-) Lo mismo ocurre solo con el tiempo - usoTIME
. ¡Para eso están estos tipos!fuente
Nullable<DateTime>
sirve?datetime2 gana en la mayoría de los aspectos, excepto (compatibilidad de aplicaciones antiguas)
tenga en cuenta los siguientes puntos
fuente de la imagen: MCTS Self-Pasion Training Kit (examen 70-432): Microsoft® SQL Server® 2008 - Implementación y mantenimiento Capítulo 3: Tablas -> Lección 1: Creación de tablas -> página 66
fuente
datetime2
es increíble (Ganador)datetime2
utiliza menos espacio de almacenamientodatetime
y ofrece un mayor alcance y una mayor precisión?Estoy de acuerdo con @marc_s y @Adam_Poward: DateTime2 es el método preferido para avanzar. Tiene un rango más amplio de fechas, mayor precisión y utiliza igual o menos almacenamiento (dependiendo de la precisión).
Una cosa que la discusión se perdió, sin embargo ...
@Marc_s establece:
Both types map to System.DateTime in .NET - no difference there
. Esto es correcto, sin embargo, lo inverso no es cierto ... y es importante cuando se realizan búsquedas de rango de fechas (por ejemplo, "encuéntrame todos los registros modificados el 5/5/2010").La versión de .NET
Datetime
tiene un rango y precisión similares aDateTime2
. Cuando se asigna un .netDatetime
al antiguo SQL, se produceDateTime
un redondeo implícito . El antiguo SQLDateTime
tiene una precisión de 3 milisegundos. Esto significa que11:59:59.997
está lo más cerca posible al final del día. Algo más alto se redondea al día siguiente.Prueba esto :
Evitar este redondeo implícito es una razón importante para pasar a DateTime2. El redondeo implícito de fechas claramente causa confusión:
fuente
20100505
a5/5/2010
? El formato anterior funcionará con cualquier región en SQL Server. Este último se romperá:SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015')
oops:2015-07-01 00:00:00.000
Casi todas las respuestas y comentarios han sido pesados en los pros y ligeros en los contras. Aquí hay un resumen de todos los pros y contras hasta ahora más algunos contras cruciales (en el n. ° 2 a continuación) que solo he mencionado una vez o no.
1.1. Más compatible con ISO (ISO 8601) (aunque no sé cómo esto entra en juego en la práctica).
1.2. Más rango (1/1/0001 a 31/12/9999 vs. 1/1 / 1753-12 / 31/9999) (aunque el rango adicional, todo antes del año 1753, probablemente no se utilizará, excepto por ej., en aplicaciones históricas, astronómicas, geológicas, etc.).
1.3. Coincide exactamente con el rango del rango de
DateTime
Tipo de .NET (aunque ambos se convierten de ida y vuelta sin una codificación especial si los valores están dentro del rango y la precisión del tipo de destino, excepto para Con # 2.1 a continuación, de lo contrario se producirá un error / redondeo).1.4. Más precisión (100 nanosegundos, también conocido como 0.000,000,1 segundos, frente a 3,33 milisegundos, también conocido como 0,003,33 segundos) (aunque la precisión adicional probablemente no se utilizará, excepto, por ejemplo, en aplicaciones de ingeniería / científicas).
1.5. Cuando se configura para una precisión similar (como en 1 milisegundo no "igual" (como en 3.33 milisegundos) como Iman Abidi ha afirmado)
DateTime
, utiliza menos espacio (7 frente a 8 bytes), pero luego, por supuesto, estaría perdiendo el beneficio de precisión que probablemente sea uno de los dos (el otro es el rango) más promocionado, aunque probablemente beneficios innecesarios).2.1. Al pasar un parámetro a un .NET
SqlCommand
, debe especificarSystem.Data.SqlDbType.DateTime2
si puede pasar un valor fuera delDateTime
rango y / o precisión del SQL Server , ya que su valor predeterminado esSystem.Data.SqlDbType.DateTime
.2.2. No se puede convertir implícita / fácilmente a un valor numérico de coma flotante (# de días desde la fecha y hora mín.) Para hacer lo siguiente con / en las expresiones de SQL Server utilizando valores numéricos y operadores:
2.2.1. sumar o restar # de días o días parciales. Nota: Usar
DateAdd
Function como solución alternativa no es trivial cuando necesita considerar múltiples, si no todas, partes de la fecha y hora.2.2.2. tome la diferencia entre dos fechas y horas para fines de cálculo de "edad". Nota: No puede simplemente usar la
DateDiff
función de SQL Server en su lugar, porque no computaage
como la mayoría de la gente esperaría si las dos fechas-hora cruzan un límite de fecha / hora de calendario / reloj de las unidades especificadas, aunque sea por una pequeña fracción de esa unidad, que va a devolver la diferencia como 1 de dicha unidad frente a 0. Por ejemplo, elDateDiff
deDay
's de dos pares fecha-hora a sólo 1 milisegundo aparte devolverá 1 vs 0 (días) si esos pares fecha-hora son en diferentes días calendario (es decir, "1999-12-31 23: 59: 59.9999999" y "2000-01-01 00: 00: 00.0000000"). La misma fecha y hora de diferencia de 1 milisegundo si se mueve para que no crucen un día calendario, devolverá un "DateDiff" enDay
's de 0 (días).2.2.3. tome la
Avg
fecha-hora (en una Consulta Agregada) simplemente convirtiendo a "Flotar" primero y luego nuevamente aDateTime
.NOTA: Para convertir
DateTime2
a un valor numérico, debe hacer algo como la siguiente fórmula, que aún asume que sus valores no son inferiores al año 1970 (lo que significa que está perdiendo todo el rango adicional más otros 217 años. Nota: puede no podrá simplemente ajustar la fórmula para permitir un rango adicional porque puede encontrarse con problemas de desbordamiento numérico.25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0
- Fuente: " https://siderite.dev/blog/how-to-translate-t-sql-datetime2-to.html "Por supuesto, también podría
Cast
aDateTime
primera (y si es necesario volver de nuevo aDateTime2
), pero se perdería la precisión y alcance (todos los anteriores a 1753 años) beneficios de laDateTime2
frenteDateTime
que son Prolly la 2 más grande y también, al mismo tiempo Prolly el 2 menos probable que sea necesario, lo que plantea la pregunta de por qué usarlo cuando pierde las conversiones implícitas / fáciles a números numéricos de punto flotante (# de días) para beneficio de suma / resta / "edad" (vs.DateDiff
) /Avg
calcs, que es uno grande en mi experiencia.Por cierto, la
Avg
fecha-hora es (o al menos debería ser) un caso de uso importante. a) Además del uso para obtener la duración promedio cuando las fechas-hora (ya que una fecha-hora base común) se usan para representar la duración (una práctica común), b) también es útil obtener una estadística de tipo panel de control sobre cuál es la fecha promedio- hora está en la columna de fecha y hora de un rango / grupo de Filas. c) Una consulta estándar (o al menos debería ser estándar) ad-hoc para monitorear / solucionar problemas en una columna que puede no ser válida alguna vez / por más tiempo y / o que deba ser desaprobada es enumerar para cada valor el recuento de ocurrencias y (si está disponible) losMin
,Avg
yMax
sellos de fecha y hora asociados con ese valor.fuente
DateTime
) mucho más probables , están relacionados con los efectos en las consultas y declaraciones de SQL Server.DateTime2
que ya mencioné (debido a la alta probabilidad de desbordamiento)). Re. "no funciona para la mayoría de los tipos de fecha": solo necesita que funcione con uno, y la mayoría de las fechas en la mayoría de las aplicaciones probablemente nunca necesitarán convertirse a otro tipo de fecha para toda su vida (excepto tal vez, como también mencioné ,DateTime2
aDateTime
(por ejemplo, para hacer "la aritmética de fechas"; P) Teniendo en cuenta que, no vale la pena todo el extra de codificación no sólo programar sino también consultas ad-hoc de investigación para utilizar un no-aritmética tipo de fecha amigable..DateTime2 causa estragos si es un desarrollador de Access que intenta escribir Now () en el campo en cuestión. Acabo de hacer una migración de Access -> SQL 2008 R2 y puso todos los campos de fecha y hora como DateTime2. Agregar un registro con Now () como el valor bombardeado. Estuvo bien el 1/1/2012 2:53:04 PM, pero no el 1/10/2012 2:53:04 PM.
Una vez que el personaje hizo la diferencia. Espero que ayude a alguien.
fuente
Aquí hay un ejemplo que le mostrará las diferencias en el tamaño de almacenamiento (bytes) y la precisión entre smalldatetime, datetime, datetime2 (0) y datetime2 (7):
que vuelve
Entonces, si quiero almacenar información hasta el segundo, pero no hasta el milisegundo, puedo guardar 2 bytes cada uno si uso datetime2 (0) en lugar de datetime o datetime2 (7).
fuente
Si bien existe una mayor precisión con datetime2 , algunos clientes no admiten date , time o datetime2 y lo obligan a convertir a un literal de cadena. Específicamente, Microsoft menciona problemas ODBC, OLE DB, JDBC y SqlClient de "nivel inferior" con estos tipos de datos y tiene un gráfico que muestra cómo cada uno puede mapear el tipo.
Si se compara el valor con la precisión, use datetime
fuente
Pregunta anterior ... Pero quiero agregar algo que no haya dicho nadie aquí ... (Nota: esta es mi propia observación, así que no solicite ninguna referencia)
Datetime2 es más rápido cuando se usa en criterios de filtro.
TLDR:
En SQL 2016 tenía una tabla con cien mil filas y una columna de fecha y hora ENTRY_TIME porque era necesario almacenar el tiempo exacto en segundos. Mientras ejecutaba una consulta compleja con muchas combinaciones y una subconsulta, cuando usaba la cláusula where como:
La consulta estuvo bien inicialmente cuando había cientos de filas, pero cuando aumentó el número de filas, la consulta comenzó a dar este error:
Eliminé la cláusula where, e inesperadamente, la consulta se ejecutó en 1 segundo, aunque ahora se obtuvieron TODAS las filas para todas las fechas. Ejecuté la consulta interna con la cláusula where, y tardó 85 segundos, y sin la cláusula where tardó 0.01 segundos.
Encontré muchos hilos aquí para este problema como rendimiento de filtrado de fecha y hora
Optimicé la consulta un poco. Pero la velocidad real que obtuve fue cambiando la columna datetime a datetime2.
Ahora, la misma consulta que expiró anteriormente lleva menos de un segundo.
salud
fuente
La interpretación de las cadenas de fecha
datetime
y tambiéndatetime2
puede ser diferente cuando se usanDATEFORMAT
configuraciones que no son de EE . UU . P.ejEsto devuelve
2013-05-06
(es decir, 6 de mayo) paradatetime
y2013-06-05
(es decir, 5 de junio) paradatetime2
. Sin embargo, condateformat
set tomdy
, both@d
y@d2
return2013-06-05
.El
datetime
comportamiento parece estar en desacuerdo con la documentación de MSDN deSET DATEFORMAT
qué estados: Algunos formatos de cadenas de caracteres, por ejemplo ISO 8601, se interpretan independientemente de la configuración DATEFORMAT . ¡Obviamente no es cierto!Hasta que me mordió esto, siempre pensé que las
yyyy-mm-dd
fechas se manejarían correctamente, independientemente de la configuración de idioma / configuración regional.fuente
SET LANGUAGE FRENCH; DECLARE @d DATETIME = '20130605'; SELECT @d;
Inténtalo de nuevo con los guiones.Según este artículo , si desea tener la misma precisión de DateTime usando DateTime2, simplemente debe usar DateTime2 (3). Esto debería darle la misma precisión, ocupar uno menos bytes y proporcionar un rango ampliado.
fuente
Me encontré con una ventaja más para
DATETIME2
: evita un error en eladodbapi
módulo Python , que explota si se pasa undatetime
valor de biblioteca estándar que tiene microsegundos distintos de cero para unaDATETIME
columna pero funciona bien si la columna se define comoDATETIME2
.fuente
El SQL anterior no funcionará con un campo DateTime2. Se devuelve y error "Choque de tipo de operando: datetime2 es incompatible con int"
Agregar 1 para obtener el día siguiente es algo que los desarrolladores han estado haciendo con fechas durante años. Ahora Microsoft tiene un campo súper nuevo datetime2 que no puede manejar esta funcionalidad simple.
"Usemos este nuevo tipo que es peor que el anterior", ¡no lo creo!
fuente
datetime
ydatetime2
tipos de datos fueron ambos introducidos en SQL Server 2008. También puede obtenerOperand type clash: date is incompatible with int
a partir deldate
tipo que ha existido desde los días de puntos. Sindateadd(dd, 1, ...)
embargo, los tres tipos de datos funcionan bien .Creo que
DATETIME2
es la mejor manera de almacenar eldate
, porque tiene más eficiencia que elDATETIME
. EnSQL Server 2008
puede usarDATETIME2
, almacena una fecha y hora, tarda 6-8bytes
en almacenar y tiene una precisión de100 nanoseconds
. Por lo tanto cualquier persona que necesite una mayor precisión el tiempo va a quererDATETIME2
.fuente