Como calcular dias úteis com os feriados nacionais

Prazos de entrega, vencimentos e SLAs costumam contar dias úteis: sem sábados, domingos e feriados. Este guia mostra como listar os feriados nacionais de qualquer ano, inclusive a Sexta-feira Santa, que muda com a data da Páscoa, e como somar dias úteis a uma data em JavaScript, Python e PHP, sem o fuso horário trocar o dia.

Por Leonardo Gaertner · Publicado em

Quais são os feriados nacionais

  • Datas fixas: 1º de janeiro, 21 de abril (Tiradentes), 1º de maio, 7 de setembro, 12 de outubro, 2 de novembro, 15 de novembro e 25 de dezembro.
  • 20 de novembro (Dia de Zumbi e da Consciência Negra): feriado nacional a partir de 2024, pela Lei 14.759/2023.
  • Sexta-feira Santa: dois dias antes do domingo de Páscoa, que muda todo ano. Na prática, é feriado em todo o país.
  • Carnaval (segunda e terça) e Corpus Christi são pontos facultativos no governo federal, não feriados. Mesmo assim, os bancos não abrem no Carnaval, e muitas cidades têm feriado no Corpus Christi.

Feriados estaduais e municipais, como o 9 de julho em São Paulo, ficam fora desta lista. Se o seu prazo depende de uma cidade, acrescente os feriados dela. Para conferir sem programar, a página de dias úteis e feriados lista os feriados de qualquer ano, o contador de dias entre datas conta os dias úteis de um período, e a calculadora de somar dias a uma data acha o vencimento em dias úteis.

Como calcular a Páscoa

A Páscoa cai no primeiro domingo depois da primeira lua cheia da primavera no hemisfério norte, uma regra que vira uma conta de restos de divisão. O algoritmo de Meeus, Jones e Butcher dá a data para qualquer ano do calendário gregoriano. Dela saem a Sexta-feira Santa (2 dias antes), o Carnaval (47 e 48 dias antes) e o Corpus Christi (60 dias depois).

As datas são tratadas em UTC e como texto AAAA-MM-DD, para o fuso horário da máquina não mudar o dia. O guia de datas e fuso horário explica por que isso importa.

JavaScript
// Datas em UTC e no formato AAAA-MM-DD, para o fuso da máquina não mudar o dia
const DIA_MS = 86_400_000;
const iso = (d) => d.toISOString().slice(0, 10);

// Domingo de Páscoa no calendário gregoriano (algoritmo de Meeus/Jones/Butcher)
function pascoa(ano) {
  const a = ano % 19;
  const b = Math.floor(ano / 100);
  const c = ano % 100;
  const g = Math.floor((b - Math.floor((b + 8) / 25) + 1) / 3);
  const h = (19 * a + b - Math.floor(b / 4) - g + 15) % 30;
  const l = (32 + 2 * (b % 4) + 2 * Math.floor(c / 4) - h - (c % 4)) % 7;
  const m = Math.floor((a + 11 * h + 22 * l) / 451);
  const n = h + l - 7 * m + 114;
  return new Date(Date.UTC(ano, Math.floor(n / 31) - 1, (n % 31) + 1));
}

function feriadosNacionais(ano, { comCarnaval = false } = {}) {
  const fixos = ['01-01', '04-21', '05-01', '09-07', '10-12', '11-02', '11-15', '12-25'];
  if (ano >= 2024) fixos.push('11-20'); // Consciência Negra, feriado nacional desde 2024
  const p = pascoa(ano).getTime();
  const datas = fixos.map((md) => `${ano}-${md}`);
  datas.push(iso(new Date(p - 2 * DIA_MS))); // Sexta-feira Santa
  // Carnaval é ponto facultativo, mas bancos e muitas empresas não abrem
  if (comCarnaval) datas.push(iso(new Date(p - 48 * DIA_MS)), iso(new Date(p - 47 * DIA_MS)));
  return new Set(datas);
}

function ehDiaUtil(data, opcoes) {
  const d = new Date(`${data}T00:00:00Z`);
  const semana = d.getUTCDay(); // 0 = domingo, 6 = sábado
  return semana !== 0 && semana !== 6 && !feriadosNacionais(d.getUTCFullYear(), opcoes).has(data);
}

// Soma n dias úteis a uma data (n negativo volta no tempo)
function somarDiasUteis(data, n, opcoes) {
  let d = new Date(`${data}T00:00:00Z`);
  const passo = n >= 0 ? 1 : -1;
  for (let faltam = Math.abs(n); faltam > 0; ) {
    d = new Date(d.getTime() + passo * DIA_MS);
    if (ehDiaUtil(iso(d), opcoes)) faltam--;
  }
  return iso(d);
}

Exemplo: somarDiasUteis("2026-04-02", 1) dá "2026-04-06", pulando a Sexta-feira Santa e o fim de semana.

Em Python e PHP

Em Python, o tipo date não tem fuso, o que evita o problema do dia trocado. As três versões dão a mesma lista de feriados e a mesma contagem de dias úteis.

Python
from datetime import date, timedelta


def pascoa(ano: int) -> date:
    """Domingo de Páscoa no calendário gregoriano (algoritmo de Meeus/Jones/Butcher)."""
    a, b, c = ano % 19, ano // 100, ano % 100
    h = (19 * a + b - b // 4 - (b - (b + 8) // 25 + 1) // 3 + 15) % 30
    l = (32 + 2 * (b % 4) + 2 * (c // 4) - h - c % 4) % 7
    m = (a + 11 * h + 22 * l) // 451
    n = h + l - 7 * m + 114
    return date(ano, n // 31, n % 31 + 1)


def feriados_nacionais(ano: int, com_carnaval: bool = False) -> set[date]:
    fixos = [(1, 1), (4, 21), (5, 1), (9, 7), (10, 12), (11, 2), (11, 15), (12, 25)]
    if ano >= 2024:
        fixos.append((11, 20))  # Consciência Negra
    p = pascoa(ano)
    datas = {date(ano, m, d) for m, d in fixos} | {p - timedelta(days=2)}
    if com_carnaval:
        datas |= {p - timedelta(days=48), p - timedelta(days=47)}
    return datas


def eh_dia_util(d: date, com_carnaval: bool = False) -> bool:
    return d.weekday() < 5 and d not in feriados_nacionais(d.year, com_carnaval)


def somar_dias_uteis(d: date, n: int, com_carnaval: bool = False) -> date:
    passo = 1 if n >= 0 else -1
    faltam = abs(n)
    while faltam:
        d += timedelta(days=passo)
        if eh_dia_util(d, com_carnaval):
            faltam -= 1
    return d
PHP
<?php
// Domingo de Páscoa (Meeus/Jones/Butcher).
// A função easter_date do PHP também resolve, mas depende da extensão calendar.
function pascoa(int $ano): DateTimeImmutable
{
    $a = $ano % 19;
    $b = intdiv($ano, 100);
    $c = $ano % 100;
    $h = (19 * $a + $b - intdiv($b, 4) - intdiv($b - intdiv($b + 8, 25) + 1, 3) + 15) % 30;
    $l = (32 + 2 * ($b % 4) + 2 * intdiv($c, 4) - $h - $c % 4) % 7;
    $m = intdiv($a + 11 * $h + 22 * $l, 451);
    $n = $h + $l - 7 * $m + 114;
    return new DateTimeImmutable(sprintf('%04d-%02d-%02d', $ano, intdiv($n, 31), $n % 31 + 1));
}

function feriadosNacionais(int $ano): array
{
    $datas = array_map(
        fn($md) => "$ano-$md",
        ['01-01', '04-21', '05-01', '09-07', '10-12', '11-02', '11-15', '12-25']
    );
    if ($ano >= 2024) {
        $datas[] = "$ano-11-20"; // Consciência Negra
    }
    $datas[] = pascoa($ano)->modify('-2 days')->format('Y-m-d'); // Sexta-feira Santa
    return $datas;
}

function ehDiaUtil(string $data): bool
{
    $d = new DateTimeImmutable($data);
    $feriados = feriadosNacionais((int) $d->format('Y'));
    // N: de 1 (segunda) a 7 (domingo)
    return (int) $d->format('N') < 6 && !in_array($data, $feriados, true);
}

Cuidados

  • Combine se o prazo conta o dia inicial. "Entrega em 5 dias úteis" a partir de uma segunda costuma terminar na segunda seguinte, mas há contratos que contam diferente.
  • Para muitas consultas, gere a lista de feriados do ano uma vez e guarde, em vez de recalcular a cada dia.
  • Prazos legais, como os de processos judiciais, têm regras próprias de contagem e suspensão. Confira a regra do seu caso.
  • Se precisar de feriados estaduais e municipais, use uma fonte que os mantenha, como uma API de feriados, porque eles mudam com leis locais.

Achou um erro neste guia? Avise por e-mail.

Perguntas frequentes

Quais são os feriados nacionais do Brasil?

1º de janeiro, 21 de abril, 1º de maio, 7 de setembro, 12 de outubro, 2 de novembro, 15 de novembro, 20 de novembro (desde 2024) e 25 de dezembro, além da Sexta-feira Santa, que muda com a Páscoa.

Carnaval é feriado nacional?

Não. Carnaval é ponto facultativo no governo federal. Mesmo assim, bancos não abrem na segunda e na terça de Carnaval, e muitas empresas também param. Por isso a função deste guia tem a opção de incluir o Carnaval.

Como calcular a data da Páscoa?

Use o algoritmo de Meeus, Jones e Butcher, uma sequência de divisões que dá o domingo de Páscoa de qualquer ano do calendário gregoriano. Em 2026, a Páscoa cai em 5 de abril.

O 20 de novembro é feriado em todo o Brasil?

Sim, desde 2024. A Lei 14.759/2023 tornou o Dia Nacional de Zumbi e da Consciência Negra feriado nacional. Antes, ele era feriado só em alguns estados e cidades.