Ir al contenido principal

Formato de fechas en SQL Server

Resumen: En cada país, en cada idioma, en cada región... usamos un formato diferente para representar las fechas. SQL Server permite comparar columnas que almacenan fechas contra cadenas de textos que convierte internamente al tipo de datos necesario. Sin embargo, según la configuración regional del servidor, la misma cadena puede ser interpretada de diferentes formas, generando errores que incluso pueden pasar inadvertidos. Para solucionarlo existe un formato de fecha estándar e independiente de cualquier configuración que hay que usar siempre: 'yyyymmdd'.


El problema

Todos sabemos que las fechas no se representan igual en todas las partes del mundo. Mientras que en España, por ejemplo, es típico usar el formato dd/mm/yyyy, donde d es día, m es año y la y representa al año (la fecha de publicación de este artículo en dicho formato sería 20/02/2014), en Alemania se usaría dd.mm.yyyy, pero en Estados Unidos sería mm/dd/yyyy.

Así pues, como se puede observar en este extenso artículo de la Wikipedia, el mismo dato se puede representar de múltiples formas; una misma fecha puede representarse con distintas ordenaciones de sus componentes y con distintos separadores entre ellos.

Por ello, es inevitable que cuando queramos poner una fecha en una consulta para compararla contra un campo de tipo date, datetime o datetime2 nos preguntemos: "¿en qué formato la pongo?"

La importancia del formato

El mismo formato puede funcionar, no funcionar o devolver resultados incorrectos, según lo que espere el servidor contra el que trabajemos. No es una cuestión trivial, ya que equivocarse en el formato puede producir resultados inesperados en el peor momento.

Supongamos que tenemos una base de datos de compras en nuestro entorno de desarrollo con la que trabajamos en español y queremos obtener todos los pedidos hechos el 12 de febrero de 2014.

La consulta que realizaríamos sería la siguiente:
Esta consulta funcionaría correctamente siempre y cuando la ejecutásemos solamente en servidores configurados en español. Sin embargo, si la ejecutásemos contra un servidor configurado en inglés, ¡estaríamos pidiendo de repente los pedidos generados el 2 de diciembre de 2014!

Tendríamos, pues, un error que pasaría inadvertido hasta que un usuario se diese cuenta de que no está obteniendo los resultados que esperaba. Esto puede tener consecuencias bastante desastrosas para consultas que afecten a fechas de caducidad, contabilidad, programas de fidelización de clientes... ¡cualquier cosa!

Puedes hacer la siguiente prueba para comprender mejor lo que está ocurriendo (además de SET LANGUAGE, existe el comando SET DATEFORMAT, que también puede cambiar la forma de SQL Server de interpretar una fecha):

Verás que el resultado cambia. En inglés se nos devuelve el mes December (diciembre), mientras que en español el mes resultante es mayo. Si la fecha consultada hubiese sido del día 13 en adelante de cualquier mes, se habría producido directamente un error ejecutando la consulta contra cualquier servidor configurado en inglés o cualquier otro idioma que espere un formato del tipo mm/dd/yyyy.

El formato independiente, al rescate

Para solucionar estos problemas existe un formato universal, que SQL Server entiende siempre, y que es totalmente independiente de cualquier configuración del servidor.

Cualquier fecha representada de la siguiente manera es interpretada siempre correctamente:

'yyyymmdd'

Así pues, en nuestro ejemplo anterior, para pedir los pedidos del día 12 de febrero de 2014, utilizaríamos la siguiente consulta:


Se puede comprobar, imitando el script de prueba anterior, que a SQL Server no le afecta en absoluto la configuración actual de idioma:

Esta vez hemos obtenido el mismo resultado tanto para inglés como para español: Febrero.

Otros formatos posibles son:
  • Para fechas cortas: 'yymmdd'
  • Para fechas con hora incluida: 'yyyymmdd hh:mm:ss.mmm'
Estos tres formatos se resumen en el patrón '[yy]yymmdd [hh:mm[:ss][.mmm]]' donde todo lo que está entre corchetes es opcional.

También existe un formato universal con separador de fechas, que siempre ha de llevar hora (solamente los milisegundos son opcionales), y que es el siguiente: 'yyyy-mm-ddThh:mm:ss.[mmm]'.

Referencias:

Comentarios

  1. Excelente información, muy claro, me sirvio mucho para los que estamos empezando en todo esto.

    Gracias

    ResponderEliminar
  2. Chamo, me has salvado!!, excelente aporte!!.

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Aprendiendo a usar LEFT OUTER JOIN

En esta entrada pretendemos explicar los diferentes resultados obtenidos por distintas construcciones de consultas que, aparentemente, deberían producir el mismo conjunto de resultados. Así, veremos las diferencias entre filtrar los resultados de una query en la unión (Join) mediante condiciones ON y mediante cláusulas WHERE.

Variantes del SELECT COUNT con DISTINCT

Seguramente, muchos de vosotros habréis usado en innumerables ocasiones la función de T-SQL COUNT , que no hace sino devolver un número de registros: de una tabla, de un conjunto de resultados, etc... En una de sus aplicaciones, combinado con el DISTINCT -uno de los dos argumentos que admite- COUNT nos devuelve el número de valores únicos no nulos de la tabla o conjunto de resultados que estemos consultando. Pero ¡ojo! Cuidado con la sintaxis , o podemos obtener el valor equivocado sin darnos cuenta. No es lo mismo: SELECT COUNT (DISTINCT NombreCampo) FROM NombreTabla que: SELECT COUNT(*), DISTINCT NombreCampo FROM NombreTabla

Script para obtener el tamaño de todas las tablas de la base de datos

En algunas ocasiones podemos vernos con la necesidad de conocer qué tablas de nuestra base de datos están ocupando más espacio en disco. Por ejemplo, si disponemos de SQL Server Express , cuyas bases de datos están limitadas a 4GB o 10GB, según la versión que estemos usando -4, hasta 2005; 10, a partir de 2008-, aparte de usar las opciones de comprimir la base de datos, poner el log en el modo simple de recuperación o ajustar las políticas de crecimiento automático de nuestros ficheros, podemos necesitar averiguar qué tablas crecen más para tomar las decisiones oportunas.