Colombia tiene 18 feriados nacionales al año, más que cualquier otro país de LATAM. Pero el número no es el único problema: diez de esos 18 feriados se mueven al lunes siguiente si no caen en lunes. Eso se llama la Ley Emiliani (Ley 51/1983), y es lo que hace que un array hardcodeado de fechas sea inútil para años distintos.
La regla de la Ley Emiliani
La ley establece dos categorías:
Feriados inamovibles — se celebran el día exacto, sin importar el día de la semana:
- Año Nuevo (1 ene)
- Día del Trabajo (1 may)
- Día de la Independencia (20 jul)
- Batalla de Boyacá (7 ago)
- Día de la Raza / Día de la Diversidad Cultural (12 oct — inamovible desde 2012)
- Inmaculada Concepción (8 dic)
- Navidad (25 dic)
- Jueves Santo y Viernes Santo (fechas variables por Pascua)
Feriados trasladables al lunes — si no caen en lunes, se observan el lunes siguiente:
- Reyes Magos (6 ene → lunes)
- San José (19 mar → lunes)
- Ascensión del Señor (jueves 39 días después de Pascua → lunes siguiente)
- Corpus Christi (jueves 60 días después de Pascua → lunes siguiente)
- Sagrado Corazón (viernes 68 días después de Pascua → lunes siguiente)
- San Pedro y San Pablo (29 jun → lunes)
- Asunción de la Virgen (15 ago → lunes)
- Todos los Santos (1 nov → lunes)
- Independencia de Cartagena (11 nov → lunes)
Los tres feriados relacionados con Pascua (Ascensión, Corpus Christi, Sagrado Corazón) son especialmente complicados: su fecha base ya es variable (depende de la fecha de Pascua), y encima se trasladan al lunes siguiente.
El problema en código
Veamos qué pasa en 2026 con Reyes Magos:
- 6 de enero de 2026 = martes
- Por la Ley Emiliani, se observa el lunes siguiente = 12 de enero
Si tu sistema verifica si el 6 de enero es hábil en Colombia:
// ❌ INCORRECTO — hardcodeado con la fecha original
const FERIADOS_CO_2026 = ["2026-01-01", "2026-01-06", ...];
const esFeriado = FERIADOS_CO_2026.includes("2026-01-06"); // true — equivocado
El 6 de enero de 2026 es día hábil en Colombia. El feriado es el 12.
Implementación correcta con la API
El enfoque más simple es no implementar la lógica: delegarla a la API, que ya tiene los feriados trasladados correctamente para cada año.
const API = "https://api.feriados.io/v1"; const KEY = process.env.FERIADOS_API_KEY;async function isBusinessDayColombia(date) { const res = await fetch(
${API}/CO/is-business-day?date=${date}, { headers: { “Authorization”:Bearer ${KEY}} } ); const { data } = await res.json(); return data.is_business_day; }// 6 de enero 2026 — ¿hábil? console.log(await isBusinessDayColombia(“2026-01-06”)); // true ✓
// 12 de enero 2026 — ¿hábil? console.log(await isBusinessDayColombia(“2026-01-12”)); // false ✓ (Reyes Magos trasladado)
Obtener todos los feriados del año con sus fechas reales
La API devuelve las fechas de celebración real (no las originales):
async function getFeriadosColombia(year) {
const res = await fetch(
`${API}/CO/holidays/${year}`,
{ headers: { "Authorization": `Bearer ${KEY}` } }
);
const { data } = await res.json();
return data;
}
const feriados2026 = await getFeriadosColombia(2026);
[
{ "date": "2026-01-01", "name": "Año Nuevo", ... },
{ "date": "2026-01-12", "name": "Reyes Magos", ... }, // ← 12, no 6
{ "date": "2026-03-23", "name": "San José", ... }, // ← 23, no 19
...
]
Calcular días hábiles entre fechas en Colombia
import os, requestsAPI = “https://api.feriados.io/v1” KEY = os.environ[“FERIADOS_API_KEY”] HDR = {“Authorization”: f”Bearer {KEY}”}
def business_days_between(start: str, end: str, country: str = “CO”) -> int: """Días hábiles entre dos fechas en un país dado.""" r = requests.get( f”{API}/{country}/business-days/between”, params={“from”: start, “to”: end}, headers=HDR, ) return r.json()[“data”][“business_days”]
¿Cuántos días hábiles tiene enero 2026 en Colombia?
dias = business_days_between(“2026-01-01”, “2026-01-31”)
→ 20 (en lugar de 21 si ignoraras Reyes Magos)
print(f”Días hábiles enero 2026 en Colombia: {dias}“)
Nómina y liquidaciones en Colombia
El cálculo de nómina en Colombia usa días hábiles para algunos conceptos (licencias, vacaciones proporcionales) y días calendario para otros. Cuando el período de liquidación cruza un feriado trasladado, el error puede ser silencioso:
// Verificar si una fecha de pago de nómina cae en feriado
async function validarFechaNomina(fechaPago, pais = "CO") {
const res = await fetch(
`${API}/${pais}/is-business-day?date=${fechaPago}`,
{ headers: { "Authorization": `Bearer ${KEY}` } }
);
const { data } = await res.json();
if (!data.is_business_day) {
// Buscar el día hábil anterior
const prevRes = await fetch(
${API}/${pais}/business-days/subtract?date=${fechaPago}&days=1,
{ headers: { “Authorization”: Bearer ${KEY} } }
);
const { data: prevData } = await prevRes.json();
return {
fechaOriginal: fechaPago,
esHabil: false,
fechaAjustada: prevData.result_date,
accion: “Adelantar pago al día hábil anterior”
};
}
return { fechaOriginal: fechaPago, esHabil: true, fechaAjustada: fechaPago };
}
const resultado = await validarFechaNomina(“2026-01-12”); // Reyes Magos
// { fechaOriginal: “2026-01-12”, esHabil: false, fechaAjustada: “2026-01-09”, … }
Días hábiles de Colombia en 2026 por mes
Días hábiles Colombia 2026
Incluye feriados con fechas trasladadas por Ley Emiliani
*Junio 2026: Sagrado Corazón cae el viernes 26, se traslada al lunes 29 — lo que hace que junio tenga 3 feriados entre semana.
Consulta los feriados de Colombia desde tu app
Fechas trasladadas correctas para cada año, sin mantener lógica de Ley Emiliani.
API key gratis →