Inside the Datetime Data (Los valores Datetime a fondo)
Solving the Datetime Mistery (Resolviendo el misterio de los valores Datetime)
Sin embargo, a mí me encanta jugar con DBCC PAGEy mirar dentro de la información que se almacena para aprender cómo trabaja realmente SQL Server.
SQL Server almacena las fechas siempre en un formato binario que es independiente del formato de salida que seleccione el usuario. Este formato binario es el conjunto de dos partes, una que representa la fecha (número de días desde la fecha origen) y otra parte representa hora (número de ticks desde medianoche).
Si se trata de un smalldatetime, la parte de fecha se almacena como el número días que han pasado desde el 1 de Enero de 1900, si se trata de un campo datetime, este valor sería negativo si se tratara de una fecha anterior al 1 de Enero de 1900.
Si se trata de un smalldatetime, la parte de hora almacena el número de minutos que han pasado desde la medianoche, mientras que si se trata de un campo datetime, la parte de hora almacenará cuántos trescientosavos de segundo han pasado desde la medianoche.
Si quieres ver cómo SQL Server almacena estos valores binarios, ejecuta el siguiente script:
USE Tempdb
GO
CREATE TABLE MiFecha (Fecha datetime,
Fechita smalldatetime)
INSERT MiFecha
SELECT Getdate(), GetDate()
INSERT MiFecha
SELECT ‘1/1/1800’, GetDate()
INSERT MiFecha
SELECT ‘1/1/1800 10:15’, GetDate()
GO
SELECT *
FROM sysindexes
WHERE id = OBJECT_ID(‘MiFecha’)
— En mi caso, veo que el campo First es 0x4B0000000100,
— esto quiere decir que la página en la que se almacenan los
— datos es la 0x4B, o sea la 75
DBCC TRACEON(3604)
DBCC PAGE (Tempdb, 1, 75, 3)
/* verás que hay tres registros con los valores que has almacenado En mi caso, he obtenido esto:
Slot 0 Offset 0x60
——————
Record Type = PRIMARY_RECORD
Record Attributes = NULL_BITMAP
1A786060: 00100010 00610fa5 00009421 94210161 ……a.!…a.!.
1A786070: 000002 …
Fecha = Oct 29 2003 5:53AM
Fechita = Oct 29 2003 5:53AM
Slot 1 Offset 0x73
——————
Record Type = PRIMARY_RECORD
Record Attributes = NULL_BITMAP
1A786073: 00100010 00000000 ffff7154 94210167 ……..Tq..g.!.
1A786083: 000002 …
Fecha = Jan 1 1800 12:00AM
Fechita = Oct 29 2003 5:59AM
Slot 2 Offset 0x86
——————
Record Type = PRIMARY_RECORD
Record Attributes = NULL_BITMAP
1A786086: 00100010 00a8ea30 ffff7154 9421016e ….0…Tq..n.!.
1A786096: 000002 …
Fecha = Jan 1 1800 10:15AM
Fechita = Oct 29 2003 6:06AM
Si jugamos un poco con valores hexadecimales,
0x9421 = 37921 dias
*/
SELECT DATEADD(day, 37921, ‘1/1/1900’)
— nos da 2003-10-29
— 0xffff7154 = 4294930772 = -36524 (si le restamos 256*256*256*256)
SELECT DATEADD(day, -36524, ‘1/1/1900’)
— nos da 1800-01-01
— 0x0161 = 353 minutos = 5:53 (la hora en la que ejecuté el script)
— 0x00a8ea30 = 11070000 ticks = 36900 segundos = 615 minutos = 10:15