17 febrero 2011

Fechas SQL Server

Es probable que lo sepas, pero lo tengo que decir para aquellos que no:

SQL Server no guarda las fechas con ningún formato, las fechas se almacenan como si fueran un float.

Es decir, no te quejes de SQL Server si tienes problemas porque tu le mandas '03/02/2011' esperando que guarde '03 de Febrero del 2011' y te encuentras con que se guardo '02 de Marzo del 2011'.

Esos problemas de conversión se dan por diferencias en la configuracion, ya sea del servidor o de los equipos de los usuarios conectados.

Pero empecemos por el principio, como guarda MSSQL las fechas?,  los datos tecnicos no los conozco a detalle, pero por lo que se puede leer en la auyda en linea de MSSQL el tipo de datos DATETIME se almacena en 8 bytes en alguna especie de dato numérico/decimal.

La forma como se mide el tiempo es empezando a contar los dias a partir del '1900/01/01' asi pues hoy 17 de Febrero del 2011 le corresponde el dia numero 40,589, la hora y los segundos se miden con ayuda de la parte decimal, es decir las 16:00 horas le corresponde un .5821 aproximadamente.

Para comprobar esto que les acabo de decir, simplemente pueden hacer un cast a un par de fechas, o al contrario un cast a un tipo decimal convirtiendolo en fecha, por ejemplo:


SELECT CAST (0 AS DATETIME)

Esta consulta nos retorna '1900-01-01 00:00:00.000', si convertimos al contrario una fecha veremos que nos retona un decimal:

SELECT CAST(CAST('20120101 08:00:00.000' AS DATETIME) AS FLOAT)

Nos da como resultado 40907.3333333333.

Entonces, por que tenemos tantos problemas los programadores con los formatos de fecha?, simple, nos confiamos, si hoy estoy desarrollando en una maquina con windows y configuracion regional de México, nadie me dice que  dentro de 1 mes algun cliente corra mi sistema en la maquina con configuracion regional de españa, US, China, etc.

Entonces?, Evita usar expresiones literales dentro de tu código del tipo: '05/08/2011', si lo tienes que hacer por fuerza, utiliza una notación que no se preste a confusión, la ISO es una buena opción, tiene el formato yyyy/mm/dd, incluso puedes omitir los caracteres de separación sin problema: yyyymmdd, por ejemplo '20100502' SQL lo interpretara como 02 de Mayo del 2010.

Adicional a esto, al menos en Delphi, todos los componentes que manejan fechas tienen la propiedad .date la cual nos da su valor numérico, evitar también usar su propiedad text pues esa tiene formato y puede causar problemas.

Espero te ayude la información