Aprende SQL · lección gratuita

Lección 11 · Fechas y tiempo

Resumen

En SQLite no existe un tipo DATE nativo: las fechas se guardan como TEXT en formato ISO 'YYYY-MM-DD'. Este formato es clave porque ordena alfabéticamente igual que cronológicamente y es compatible con todas las funciones de fecha. Con strftime, date, julianday y aritmética de intervalos puedes extraer partes, sumar meses, calcular antigüedad y agrupar por periodo.

Sintaxis / Conceptos

Las fechas son texto, pero ordenan bien

Como el formato es 'YYYY-MM-DD', una comparación de texto fecha >= '2024-01-01' funciona perfectamente como filtro cronológico, y ORDER BY fecha ordena en el tiempo. No necesitas convertir nada para filtrar rangos: WHERE fecha BETWEEN '2023-01-01' AND '2023-12-31'.

Extraer partes con strftime

strftime siempre devuelve TEXT, incluso para el año o el mes. Por eso strftime('%Y', fecha) devuelve '2023' (cadena). Si necesitas operar aritméticamente (restar años, comparar como número) envuélvelo en CAST(strftime('%Y', fecha) AS INTEGER) o súmale 0. Esto enlaza con la lección 12 sobre conversión de tipos.

Calcular antigüedad de empleados

La forma robusta de la antigüedad en años completos es con julianday: cuentas los días entre la contratación y una fecha de referencia, y divides entre 365.25 (promedio que compensa años bisiestos). El CAST(... AS INTEGER) trunca a años enteros. Usamos una fecha de referencia fija ('2024-06-01') en los ejemplos para que el resultado sea reproducible; en producción usarías date('now').

Sumar y restar intervalos con date()

date(fecha, '+1 month') te da el mismo día del mes siguiente; encadenas modificadores: date(fecha, '+1 year', 'start of month'). Cuidado con fines de mes: date('2024-01-31', '+1 month') produce '2024-03-02', porque febrero no tiene día 31 y SQLite normaliza el desbordamiento.

SELECT nombre, fecha_contratacion, strftime('%Y', fecha_contratacion) AS anio FROM empleados ORDER BY fecha_contratacion LIMIT 6

Ejemplos

-- Antigüedad de cada empleado en años completos a una fecha de referencia fija.
-- julianday cuenta días; dividir entre 365.25 y truncar da años enteros.
SELECT
  nombre,
  fecha_contratacion,
  CAST((julianday('2024-06-01') - julianday(fecha_contratacion)) / 365.25 AS INTEGER) AS antiguedad_anios
FROM empleados
ORDER BY antiguedad_anios DESC, id
LIMIT 8;

-- Extraer partes de la fecha y construir el año-mes del pedido.
SELECT
  id,
  fecha,
  strftime('%Y', fecha)    AS anio,
  strftime('%m', fecha)    AS mes,
  strftime('%Y-%m', fecha) AS periodo
FROM pedidos
ORDER BY fecha
LIMIT 6;

-- Pedidos agrupados por mes (volumen mensual).
SELECT
  strftime('%Y-%m', fecha) AS periodo,
  COUNT(*)                 AS total_pedidos
FROM pedidos
GROUP BY periodo
ORDER BY periodo;

-- Aritmética de fechas: fecha de renovación = un año después del alta del cliente.
SELECT
  empresa,
  fecha_alta,
  date(fecha_alta, '+1 year') AS proxima_renovacion,
  CAST(julianday('2024-06-01') - julianday(fecha_alta) AS INTEGER) AS dias_como_cliente
FROM clientes
ORDER BY fecha_alta
LIMIT 6;
💡 strftime devuelve siempre texto. Si comparas strftime('%m', fecha) = 5 fallará silenciosamente porque comparas '05' (texto) con 5 (número). Usa strftime('%m', fecha) = '05' o CAST(strftime('%m', fecha) AS INTEGER) = 5.

Cheatsheet

FunciónQué hace
strftime('%Y', f)Año como texto ('2023')
strftime('%m', f) / '%d'Mes / día como texto ('05', '14')
strftime('%Y-%m', f)Año-mes, ideal para agrupar
date(f, '+1 month')Suma/resta intervalos ('+N days/months/years')
date(f, 'start of month')Primer día del mes
julianday(f)Día juliano (número); resta = diferencia en días
(jd_a - jd_b) / 365.25Diferencia aproximada en años

---

← Funciones de textoConversión de tipos: CAST, COALESCE y NULLIF →

Ver todas las lecciones de Aprende SQL →