feriados.io ← Inicio
javascripttutorialdias-habilesdesarrollo

Calcular días hábiles en JavaScript: por qué las soluciones caseras fallan

Cómo calcular días hábiles entre dos fechas en JavaScript. Los errores más comunes con las soluciones DIY y cuándo usar una API externa.

10 de septiembre de 2025

Calcular días hábiles entre dos fechas parece un problema resuelto. Hay decenas de snippets en Stack Overflow. Pero la mayoría falla en producción por razones que no son obvias hasta que el error ya llegó a un cliente.

El snippet básico que todos usan

function countBusinessDays(startDate, endDate) {
  let count = 0;
  const current = new Date(startDate);

  while (current <= endDate) {
    const day = current.getDay();
    if (day !== 0 && day !== 6) count++;
    current.setDate(current.getDate() + 1);
  }

  return count;
}

Este código cuenta días de lunes a viernes. Funciona bien para un test unitario. Falla en producción porque no considera feriados.

El segundo intento: hardcodear feriados

const FERIADOS_2026 = new Set([
  "2026-01-01",
  "2026-04-03",
  "2026-04-04",
  "2026-05-01",
  // ...
]);

function countBusinessDays(startDate, endDate) {
  let count = 0;
  const current = new Date(startDate);

  while (current <= endDate) {
    const day = current.getDay();
    const iso = current.toISOString().split("T")[0];
    if (day !== 0 && day !== 6 && !FERIADOS_2026.has(iso)) count++;
    current.setDate(current.getDate() + 1);
  }

  return count;
}

Funciona para 2026. El 1 de enero de 2027, el array está desactualizado y alguien tiene que acordarse de actualizarlo.

El tercer problema: zonas horarias

const fecha = new Date("2026-04-03");
console.log(fecha.toISOString()); // "2026-04-02T21:00:00.000Z" en UTC-3

Si tu servidor corre en UTC y tu usuario está en Santiago (UTC-3), new Date("2026-04-03") puede ser el 2 de abril en el servidor. El Viernes Santo se convierte en Jueves normal y el cálculo está mal.

El fix correcto:

function parseFechaLocal(dateString) {
  const [year, month, day] = dateString.split("-").map(Number);
  return new Date(year, month - 1, day); // mes es 0-indexed
}

O simplemente trabajar siempre con strings YYYY-MM-DD y no con objetos Date.

El cuarto problema: múltiples países

Si tu aplicación opera en Chile y Colombia, tienes que mantener dos listas de feriados. Y Colombia traslada sus feriados al lunes siguiente según la Ley Emiliani — eso significa que no puedes usar las fechas fijas, tienes que calcular el lunes correcto para cada año.

// Colombia: Epifanía es el 6 de enero, pero se celebra el lunes siguiente
function siguienteLunes(date) {
  const d = new Date(date);
  const dia = d.getDay();
  if (dia === 1) return d; // ya es lunes
  const diff = dia === 0 ? 1 : 8 - dia; // días hasta el próximo lunes
  d.setDate(d.getDate() + diff);
  return d;
}

const epifania2026 = siguienteLunes(new Date(2026, 0, 6));
// lunes 12 de enero

Esto hay que hacerlo para 8 feriados colombianos. Más los feriados móviles que dependen de Pascua.

Cuándo usar una API externa

La lógica DIY vale cuando:

La API externa vale cuando:

Implementación con la API de feriados.io

const API = "https://api.feriados.io/v1";
const HEADERS = { "Authorization": `Bearer ${process.env.FERIADOS_API_KEY}` };

// Contar días hábiles entre dos fechas (Team/Business)
async function countBusinessDays(pais, from, to) {
  const res = await fetch(
    `${API}/${pais}/business-days/between?from=${from}&to=${to}`,
    { headers: HEADERS }
  );
  const { data } = await res.json();
  return data.business_days;
}

// Sumar N días hábiles a una fecha (Team/Business)
async function addBusinessDays(pais, date, days) {
  const res = await fetch(
    `${API}/${pais}/business-days/add?date=${date}&days=${days}`,
    { headers: HEADERS }
  );
  const { data } = await res.json();
  return data.result_date;
}

// ¿Es hábil esta fecha? (Free)
async function isBusinessDay(pais, date) {
  const res = await fetch(
    `${API}/${pais}/is-business-day?date=${date}`,
    { headers: HEADERS }
  );
  const { data } = await res.json();
  return data.is_business_day;
}

// Uso
const diasHabiles = await countBusinessDays("CL", "2026-04-01", "2026-04-30");
// 19 (abril tiene Semana Santa)

const fechaEntrega = await addBusinessDays("CO", "2026-04-01", 10);
// "2026-04-16" (Colombia tiene Jueves y Viernes Santo + festivo del 6 trasladado)

El resultado es el mismo para ambos países con el mismo código. Sin listas, sin lógica de traslados, sin bugs de zona horaria.


¿Necesitas esto en producción? Empezar gratis — API key en 30 segundos, sin tarjeta →


Ver también: Feriados Chile 2026: lista completa → · Feriados Colombia 2026 y la Ley Emiliani → · Documentación de endpoints →

Integra feriados.io en tu proyecto

API key gratis en 30 segundos. Sin tarjeta. 11 países de Latinoamérica, siempre actualizada con los feriados oficiales.

← Ver todos los artículos