Calculando a diferença de dias úteis entre duas datas utilizando JavaScript

Calculando a diferença de dias úteis entre duas datas utilizando JavaScript

Neste artigo vamos ver como calcular a diferença de dias úteis entre duas datas utilizando JavaScript.

Primeiro vamos ver quais as datas iniciais e finais que vamos trabalhar.

 

data1 = '2021-01-01';

data2 = '2021-12-31';

 

Vamos pegar esta string de data e criar uma data utilizando a função Date()

 

var arr1 = data1.split('-');

var arr2 = data2.split('-');

var dataAtual = new Date(arr1[0],arr1[1]-1, arr1[2]);

var dataFinal = new Date(arr2[0],arr2[1]-1, arr2[2]);

 

var ano_inicial = dataAtual.getFullYear();

var ano_final = dataFinal.getFullYear();

var ano = ano_inicial;

 

Foram criados dois arrays auxiliares com o conteudo das datas informadas. Para separar uma string e converter o seu conteudo em array utilizamos o método split da string da data. O separador foi o "-". Para criar a data, com base no array auxiliar, informamos o ano, mês e dia. Usando a função Date para criar a data inicial e final evitamos problemas com fuso horário, já que a data vai respeitar o fuso horário do navegador do usuário e evitar um problema comum no cálculo de datas, onde em algum casos o resultado fica menor em 1 dia.

Uma observação muito importante. Ao trabalhar com a função Date, o primeiro mês, que é janeiro, deve ser informado como zero. Ou seja, eu preciso subtrair 1 ao mês da data informada.

Nosso próximo passo é criar um array auxiliar que contenha todos os feriados contidos dentro do intervalo de datas informado. Alguns feriados tem data fixa, e outros tem data variável. Começando pelos feriados de data fixa. Vamos criar uma função auxiliar que vai nos permitir calcular os feriados de acordo com o ano inicial e ano final informados.

function FeriadosFixos(ano){

var resultados = [];

//Array de datas no formato mes/dia.

//OBS: O primeiro mes é 0 e o último mes é 11

var datas = [[0,  1], [3,  21],[4,  1], [8,  7], [9,  12], [10,  2], [10, 15], [11, 25]];

 

for (z = 0; z < datas.length; z++){

resultados.push(new Date(ano, datas[z][0],  datas[z][1]).getTime());

}

return resultados;

}

 data1 = '2021-01-01';

data2 = '2021-12-31';

var arr1 = data1.split('-');

var arr2 = data2.split('-');

var dataAtual = new Date(arr1[0],arr1[1]-1, arr1[2]);

var dataFinal = new Date(arr2[0],arr2[1]-1, arr2[2]);

var ano_inicial = dataAtual.getFullYear();

var ano_final = dataFinal.getFullYear();

var ano = ano_inicial;

 

for (x = ano; x <= ano_final; x++){

console.log(FeriadosFixos(x));

}

Neste exemplo o resultado da função gerou um array auxiliar chamado feriados para os feriados do ano informado. Para adicionar cada data fixa no array, utilizamos novamente a função Date. Seus parâmetros na ordem são ano, mês e dia. Dentro da função auxiliar, criamos um array contendo os meses e dias dos feriados com data fixa.

 

Agora vamos ver os feriados variáveis. Os feriados com data variável dependem da data da páscoa. Primeiro, vamos criar uma função auxiliar para calcular a data da Páscoa de acordo com um ano informado

 

function Pascoa(Y) {

    var C = Math.floor(Y/100);

    var N = Y - 19*Math.floor(Y/19);

    var K = Math.floor((C - 17)/25);

    var I = C - Math.floor(C/4) - Math.floor((C - K)/3) + 19*N + 15;

    I = I - 30*Math.floor((I/30));

    I = I - Math.floor(I/28)*(1 - Math.floor(I/28)*Math.floor(29/(I + 1))*Math.floor((21 - N)/11));

    var J = Y + Math.floor(Y/4) + I + 2 - C + Math.floor(C/4);

    J = J - 7*Math.floor(J/7);

    var L = I - J;

    var M = 3 + Math.floor((L + 40)/44);

    var D = L + 28 - 31*Math.floor(M/4);

 

    return new Date(Y, M, D);

}

 

Vamos precisar também de duas funções auxiliares, para aumentar ou subtrair dias a uma data informada

 

function DataAdicionar(data_informada, quantidade) {

  var fator = 24 * 60 * 60 * 1000;

  var nova_data = new Date(data_informada.getTime() + quantidade * fator);

  nova_data.setHours(0,0,0,0);

  return nova_data;

}

function DataSubtrair(data_informada, quantidade) {

  var fator = 24 * 60 * 60 * 1000;

  var nova_data = new Date(data_informada.getTime() - quantidade * fator);

  nova_data.setHours(0,0,0,0);

  return nova_data;

}

 

E agora utilizando estas funções auxiliares, vamos calcular os feriados com data variável.

 

var feriados = [];

for (x = ano; x <= ano_final; x++){

//OBS: O primeiro mes é 0 e o último mes é 11

//Feriados fixos.

 feriados = feriados.concat(FeriadosFixos(ano));

console.log('Pascoa');

console.log(Pascoa(ano));

data_pascoa = Pascoa(ano); 

 

//Feriados variaveis de acordo com a data da Pascoa

feriados.push(data_pascoa.getTime());

feriados.push(DataAdicionar(data_pascoa, 60).getTime());

feriados.push(DataSubtrair(data_pascoa, 48).getTime());

feriados.push(DataSubtrair(data_pascoa, 47).getTime());

feriados.push(DataSubtrair(data_pascoa, 2).getTime());

ano++;

}

console.log(feriados);

 

Os feriados variáveis são a páscoa, a sexta-feira santa, os dias de carnaval e o Corpus Christi

Uma observação. Como a função FeriadosFixos retorna um array com os feriados do ano, para juntar este array com o array de feriados do período selecionado utilizamos o método concat do array de feriados.

Agora que temos os feriados, podemos verificar a quantidade de dias uteis entre duas datas. 

 

while (dataAtual <= dataFinal) {

if (dataAtual.getDay() !== 0 && dataAtual.getDay() !== 6) {

if (!feriados.includes(dataAtual.getTime())){

numDiasUteis++;

}

}

dataAtual = DataAdicionar(dataAtual,1);

}

console.log(numDiasUteis);

 

Para o calculo de dias fizemos um loop usando WHILE entre a data inicial e a data final, e fizemos o incremento da data em 1 dia usando a função auxiliar que criamos.

 

Para validar se a data atual é um feriado, utilizamos o includes do array feriados para verificar se aquela data existe no array de feriados.

 

if (!feriados.includes(dataAtual.getTime())){

numDiasUteis++;

}

 

Em nosso exemplo não consideremos o sábado e o domingo como dia útil. Para verificar o dia da semana da data informa, utilizamos o método getDay da data informada.

 

if (dataAtual.getDay() !== 0 && dataAtual.getDay() !== 6) {

//Codigo a ser executado

}

 

O retorno é um número inteiro. Ele vai retornar 6 para sábado e 0 para domingo.

 

Para encerrar, vamos criar uma função para encapsular toda esta lógica. Nosso código completo ficaria da seguinte forma:

 

function DataAdicionar(data_informada, quantidade) {

 

  var fator = 24 * 60 * 60 * 1000;

 

  var nova_data = new Date(data_informada.getTime() + quantidade * fator);

 

  nova_data.setHours(0,0,0,0);

 

  return nova_data;

 

}

 

function DataSubtrair(data_informada, quantidade) {

 

  var fator = 24 * 60 * 60 * 1000;

 

  var nova_data = new Date(data_informada.getTime() - quantidade * fator);

 

  nova_data.setHours(0,0,0,0);

 

  return nova_data;

 

}

 

function FeriadosFixos(ano){

var resultados = [];

//Array de datas no formato mes/dia.

//OBS: O primeiro mes é 0 e o último mes é 11

var datas = [[0,  1], [3,  21],[4,  1], [8,  7], [9,  12], [10,  2], [10, 15], [11, 25]];

 

for (z = 0; z < datas.length; z++){

resultados.push(new Date(ano, datas[z][0],  datas[z][1]).getTime());

}

return resultados;

}

 

 

 

function Pascoa(Y) {

 

    var C = Math.floor(Y/100);

 

    var N = Y - 19*Math.floor(Y/19);

 

    var K = Math.floor((C - 17)/25);

 

    var I = C - Math.floor(C/4) - Math.floor((C - K)/3) + 19*N + 15;

 

    I = I - 30*Math.floor((I/30));

 

    I = I - Math.floor(I/28)*(1 - Math.floor(I/28)*Math.floor(29/(I + 1))*Math.floor((21 - N)/11));

 

    var J = Y + Math.floor(Y/4) + I + 2 - C + Math.floor(C/4);

 

    J = J - 7*Math.floor(J/7);

 

    var L = I - J;

 

    var M = 3 + Math.floor((L + 40)/44);

 

    var D = L + 28 - 31*Math.floor(M/4);

 

 

 

    return new Date(Y, M, D);

 

}

 

 

 

function getnumDiasUteis(startDate, dataFinal) {

 

    var numDiasUteis = 0;

 

var arr1 = startDate.split('-');

 

var arr2 = dataFinal.split('-');

 

var dataAtual = new Date(arr1[0],arr1[1]-1, arr1[2]);

 

dataFinal = new Date(arr2[0],arr2[1]-1, arr2[2]);

 

 

 

var ano_inicial = dataAtual.getFullYear();

 

var ano_final = dataFinal.getFullYear();

 

var ano = ano_inicial;

 

 

 

var feriados = [];

 

for (x = ano; x <= ano_final; x++){

 

//OBS: O primeiro mes é 0 e o último mes é 11

 

//Feriados fixos.

 

feriados = feriados.concat(FeriadosFixos(ano));

 

data_pascoa = Pascoa(ano); 

 

 

//Feriados variaveis de acordo com a data da Pascoa

 

feriados.push(data_pascoa.getTime());

 

feriados.push(DataAdicionar(data_pascoa, 60).getTime());

 

feriados.push(DataSubtrair(data_pascoa, 48).getTime());

 

feriados.push(DataSubtrair(data_pascoa, 47).getTime());

 

feriados.push(DataSubtrair(data_pascoa, 2).getTime());

 

ano++;

 

}

 

 

    while (dataAtual <= dataFinal) {

 

if (dataAtual.getDay() !== 0 && dataAtual.getDay() !== 6) {

 

if (!feriados.includes(dataAtual.getTime())){

 

numDiasUteis++;

 

}

 

        }

 

        dataAtual = DataAdicionar(dataAtual,1);

 

    }

 

    return numDiasUteis;

 

}

 

console.log('dias uteis');

 

console.log(getnumDiasUteis('2021-01-01', '2021-12-31'));

 

Está começando e deseja saber o que precisa estudar de HTML e JavaScript? Não deixe de conferir os roteiros de estudo de HTML e JavaScript!. São dezenas de conteúdos para você melhorar suas habilidades.

Roteiro de estudos - HTML e CSS

Roteiro de estudos - Javascript

 

Outros conteudos que podem ser de seu interesse

Validar senhas com Javascript
20/10/2019JAVASCRIPT

Validar senhas com Javascript

Aprenda a criar regras para cadastrar senhas seguras

Saiba mais...
Raspagem de dados com NodeJS
08/12/2019JAVASCRIPT

Raspagem de dados com NodeJS

Veja como fazer data scraping de um site utilizando NodeJS

Saiba mais...

Conteúdo sobre banco de dados sem complicação!