Funciones de fecha: calcular periodos y construir límites seguros
Las fechas representan instantes o periodos, no textos con un formato visual. Para sumar días, medir diferencias, obtener fin de mes o construir una fecha utilizamos funciones temporales y tipos apropiados.
Una de las decisiones más importantes es expresar correctamente los rangos cuando la columna también contiene hora.
Funciones principales
| Función | Uso |
|---|---|
DATEADD |
Suma o resta una cantidad de unidades |
DATEDIFF |
Cuenta límites de unidad atravesados |
DATEFROMPARTS |
Construye una fecha con año, mes y día |
EOMONTH |
Devuelve el último día de un mes |
Ejemplo: sumar un periodo
SELECT
p.IdPedido,
p.FechaPedido,
DATEADD(DAY, 5, p.FechaPedido) AS FechaEstimada
FROM dbo.Pedido AS p;
El primer argumento indica la unidad; el segundo, la cantidad. Una cantidad negativa resta tiempo.
Medir una diferencia
SELECT
c.IdCliente,
c.FechaRegistro,
DATEDIFF(DAY, c.FechaRegistro, SYSDATETIME()) AS DiasDesdeRegistro
FROM dbo.Cliente AS c;
DATEDIFF cuenta cuántos límites de día se atravesaron. No calcula una duración decimal exacta. Dos instantes separados por pocos segundos pueden producir 1 día si se encuentran a lados distintos de la medianoche.
Construir el inicio y final de un mes
DECLARE @Anio INT = 2026;
DECLARE @Mes INT = 3;
SELECT
DATEFROMPARTS(@Anio, @Mes, 1) AS InicioMes,
EOMONTH(DATEFROMPARTS(@Anio, @Mes, 1)) AS FinMes;
Las variables creadas mediante DECLARE se explican de forma independiente en la ficha sobre variables.
DATEFROMPARTS evita depender del idioma o formato regional de una cadena.
Filtrar un rango que contiene hora
Para consultar todos los pedidos de marzo utilizamos un límite inicial inclusivo y uno final exclusivo:
DECLARE @Desde DATE = '2026-03-01';
DECLARE @Hasta DATE = '2026-04-01';
SELECT
p.IdPedido,
p.FechaPedido,
p.Estado
FROM dbo.Pedido AS p
WHERE p.FechaPedido >= @Desde
AND p.FechaPedido < @Hasta
ORDER BY p.FechaPedido;
Esta forma incluye cualquier precisión de hora dentro de marzo. Evita escribir un final como 23:59:59, que puede omitir valores con mayor precisión.
Calcular el siguiente mes
Cuando solo recibimos una fecha inicial, el límite exclusivo puede derivarse:
DECLARE @InicioMes DATE = '2026-03-01';
DECLARE @InicioSiguienteMes DATE = DATEADD(MONTH, 1, @InicioMes);
Qué conviene comprobar
Debemos distinguir DATE, DATETIME, DATETIME2 y valores con zona u offset. SYSDATETIME() utiliza el reloj local del servidor; no representa automáticamente la zona del usuario.
También evitamos convertir la columna a texto dentro del filtro. Comparar un rango temporal conserva el significado del dato y normalmente ofrece mejores posibilidades de utilizar un índice.
Relacionado con
- Conversiones: interpretan o presentan fechas cuando realmente necesitamos texto.
WHERE: expresa rangos mediante límites inclusivos y exclusivos.ORDER BY: organiza cronológicamente los resultados.- Funciones de ventana: permiten acumulados y comparaciones temporales.