calculate delivery date only taking into account the working days in javascript

0
var fechaIncio = new Date();
var fechaTotal = new Date();

var FechasFestivas = [
    [1],
    [40],
    [19, 25],
    [19, 22],
    [1],
    [24, 29],
    [40],
    [15],
    [40],
    [9, 12],
    [1],
    [6, 25],
];

fechaTotal.setDate(fechaTotal.getDate() + 10);
var diaSaDo = 0;
var diafestivo = 0;
var dom = 0;
var sab = 6;

while (fechaIncio.getDate() < fechaTotal.getDate()) {
    document.getElementById("a").prepend("dia inicio = " + fechaIncio.getDate() + "---");
    if (fechaIncio.getDay() == dom || fechaIncio.getDay() == sab) {
        diaSaDo++;
    } else {
        for (var i = 0; i <= FechasFestivas[fechaIncio.getMonth()].length; i++) {
            if (fechaIncio.getDate() == FechasFestivas[fechaIncio.getMonth()][i]) {
                diafestivo++;
            }
        }
    }
    fechaIncio.setDate(fechaIncio.getDate() + 1);
}

fechaIncio.setDate(fechaIncio.getDate() + diaSaDo + diafestivo);
    
asked by jesus farias 21.12.2018 в 23:24
source

2 answers

0

I hope this helps you, at least I would.

First of all we must establish a couple of things in your question, since I am going to assume them according to the code that you have published.

The first thing is to establish that the Array of holidays contains the holidays. However in your example you put the number 40 more than a couple of times, and to my knowledge, at least on Earth, the months have at most 31 days. I guess it's a typing mistake and so I assume. I also assume that the Array of holidays contains the days in Number format, grouped in turn in arrays according to the number of the month.

The second thing I'm going to assume, since you do not provide information about it, is that the date you receive as the start date comes in a valid format, whether String , Number or Date .

Reading your comment well, I see that the order date is the current date, therefore I make the necessary modifications.

Done those two dimensions, we'll do what we're dealing with (I'll use ES6 syntax)

// Array con los días festivos de cada mes (ejemplo de muestra)
// Nótese que si un mes no tiene festivos debemos incluir igualmente un array vacío, (ejemplo: Noviembre)
const festivos = [[1, 7, 8],[27, 28],[1],[6, 9],[1],[15],[9],[17, 18, 19],[10],[12, 23],[],[25]];

// JavaScript usa como estándar el formato de fecha ISO (YYYY-MM-DD)
// const diaPedido = new Date('2019-01-04');
// Leyendo un poco tu comentario con más atención veo que la fecha de pedido
// es la fecha actual, por lo tanto edito para que la respuesta se ajuste a tu pregunta

const diaPedido = new Date(Date.now());
// Construimos la fecha usando como parámetro el valor devuelto por Date.now().

// La siguiente función recibe como parámetros:
// diaPedido: Es el día inicial, (cuando se recibe un pedido), tipo: Date
// diasPactados: Es la cantidad de días laborales que han sido pactados para entrega, tipo: Number
// festivos: Es el Array que hemos inicializado anteriormente y contiene los días festivos del año, tipo: Array
//      Se espera que los días festivos sean fijos de año en año, pero pudieran modificarse.
//      Así que sólo hay que asegurarse de pasar el array de festivos mas actualizado a la función.

function calculaEntrega(diaPedido, diasPactados, festivos) {
    // diaPropuesto: almacena el mismo valor de diaPedido, en caso que diasPactados = 0, la función 
    // devolverá el valor de diaPedido (para mi tiene lógica)
    let diaPropuesto = new Date(diaPedido.getFullYear(), diaPedido.getMonth(), diaPedido.getDate());

    // iniciamos un contador en 1 para calcular la fecha de diaPropuesto.
    let i = 1;
    
    // El siguiente bucle se ejecutará hasta que se consuman los diasPactados
    while (diasPactados > 0 ) {
        // En cada iteración asumimos que el día no es festivo
        let festivo = false;
        // incrementamos en 1 el diaPropuesto para efectuar las verificaciones
        diaPropuesto = new Date(diaPedido.getFullYear(), diaPedido.getMonth(), diaPedido.getDate() + i);
        // Nótese que usamos formato ISO y solo incrementamos el día, dejando el mes y el año iguales
        // Alguien preguntará: ¿Y que pasa si la fecha es, digamos, 31 de Enero y le aumentamos 1 día?
        // Pues la respuesta lógica es que daría 32 de Enero, lo cual no es una fecha válida.
        // Sin embargo, JavaScript es un poco mas atento que nosotros y simplemente realiza la aritmética
        // necesaria para convertir el 32 de Enero en 01 de Febrero, y así nos salva el pellejo.
        // Véase bien que usamos los métodos getFullYear(), getMonth() y getDate().
        // Esto funciona siempre y cuando hagamos la construcción del objeto Date de esta manera.
        // Ya irá alguno de avispado y pondrá: fecha = new Date('2019-01-32'); lo cual le dará 'fecha inválida'
        // Alguien un poco mas versado puede aclarar este asunto, pero no es el objetivo en este momento.

        if (diaPropuesto.getDay() > 0 && diaPropuesto.getDay() < 6) {
            // Aquí hemos usado el método getDay() del objeto Date, este método devuelve un valor entero entre 0 y 6,
            // donde 0: Domingo, 1: Lunes, ... , 6: Sabado.
            // Los días laborables van del 1 al 5 (ambos inclusive)
            
            // Si el día es laborable debemos entonces verificar si es festivo
            
            // Aquí es importante que entendamos lo siguiente:
            //  * Por cada iteración debemos obtener el mes en el que estamos comprobando el festivo
            //  * Vamos a comparar el día propuesto con el Array de festivos, usando el mes correspondiente

            let m = diaPropuesto.getMonth();
            let dia = diaPropuesto.getDate();

            // Felizmente para nosotros el método getMonth() devuelve un entero entre 0 y 11, que se
            // corresponde con cada mes del año, y digo felizmente, porque los índices de nuestro Array
            // van de 0 a 11 también.

            for (let d in festivos[m]) {
                if (dia === festivos[m][d]) {
                    festivo = true;
                    //Aquí no hay mucho que aclarar, si es festivo ya no sigo comprobando el resto del mes.
                    break;
                }
            } // Fin bucle for

            if (!festivo) {
                // Si las condiciones son: Laborable y No Festivo, descuento el diaPactado.
                diasPactados--;
            }
        }

        // Por último, debemos incrementar el número de días que sumaremos al diaPropuesto
        // en cada iteración
        i++;
    } // Fin de bucle while

    // Devolvemos el resultado
    return diaPropuesto;

} // Fin función



// Finalmente asignamos nuestra variable diaEntrega, la cual contendra un Objeto Date valido indicando
// la fecha en que el pedido sera entregado.

const diaEntrega = calculaEntrega(diaPedido, 10, festivos);

console.log('Dia de pedido: ${diaPedido.toString()}');
console.log('Dia de entrega calculado: ${diaEntrega.toString()}');

I hope this answer is satisfactory.

A thousand greetings.

Note: Holidays are fictional.

    
answered by 04.01.2019 / 00:45
source
0

The truth is that I did not see where. I am new by consulting here the following code is a test that I have that your function is given the current date to make an order to make a delivery in 10 days or number of days but not count the weekends and the day not workdays as holidays and give the exact day as for example today Friday / 21/12/2018 is an order of 5 days begins from Monday / 24/12/2018 without counting Saturday and Sunday and Tuesday 25 / 12/2018 porq is a holiday and continues counting wednesday / 26/12/2018 so until 5 days it would be on Saturday / 29 and Sunday / 30 do not count porq is weekend and on Monday31 / 12/2018 it would be the 5 days estimated of the delivery of the order

    
answered by 21.12.2018 в 23:56