Subtract 4 times and display at the same time the result in another input

Asked

Viewed 104 times

0

I am with this doubt of how I will take these 4 fields (Time start, end and interval start and end) and subtract them and appear the answer in another input in the weekly workload.

The code is this (need a Javascript function):

<div id="divHorarios" style="display: none">
    <div class="form-group col-md-3 col-sm-4">
        <label for="horarioInicio"><br>Horário de início: <font color="red">*</font>
        </label>
        <input type="text" class="form-control" id="txtHorarioInicio"
            placeholder="Exemplo: 08:00" style="height: 43px;"/>
    </div>

    <div class="form-group col-md-3 col-sm-4">
        <label for="intervaloInicio"><br>Início do intervalo: <font color="red">*
            </font>
        </label>
        <input type="text" maxlength="5" class="form-control" id="txtIntervaloInicio"
            placeholder="Exemplo: 12:00" style="height: 43px;"/>
    </div>

    <div class="form-group col-md-3 col-sm-4">
        <label for="intervaloFim"><br>Fim do intervalo: <font color="red">*</font>
        </label>
        <input type="text" maxlength="5" class="form-control" id="txtIntervaloFim"
            placeholder="Exemplo: 13:00" style="height: 43px;"/>
    </div>

    <div class="form-group col-md-3 col-sm-4">
        <label for="horarioFim"><br>Horario de Término: <font color="red">*</font>
        </label>
        <input type="text" maxlength="5" class="form-control" id="txtHorarioFim"
            placeholder="Exemplo: 18:00" style="height: 43px;"/>
    </div>
</div>

<div class="row">
    <div class="form-group col-md-6">
        <label for="carga-horaria"><br>Carga Horária Semanal: <font color="blue">*
            </font>
        </label>
        <input type="text" style="width:150px" class="form-control" id="carga-horaria"
            placeholder="" style="height: 43px;" readonly>
    </div>
</div>

<div class="row">
    <div class="form-group col-md-6">
        <label for="carga-horaria">Carga Horária Total: <font color="blue">*</font>
        </label>
        <input type="text" style="width:150px" class="form-control" id="carga-horaria-total"
            placeholder="" style="height: 43px;" readonly>
    </div>
</div>

1 answer

1


First, you could use the input type="time" instead of type="text". If the browser is compatible and support this type, it already limits the input format to hh:mm (if the browser does not support, at the end of the answer there is an alternative).

Unfortunately the Javascript does not provide a way to work only timeslot, since the class Date actually represents a timestamp (a specific time line, and therefore may represent a different date and time in each time zone).

An alternative is to do the Parsing manually, and calculate the difference in minutes between times. The value of a field input type="time" is the time in the format hh:mm, where the time field varies between 0 and 23. Thus, a way to separate the time from the minutes is by using split to break the string into two parts, and parseInt to convert these strings to numbers. Example:

let [hora, minuto] = '10:00'.split(':').map(v => parseInt(v));

The above line works if the browser already supports Destructuring Assignment and Arrow Functions. If the browser does not support this syntax, you can do:

let partes = '10:00'.split(':');
let hora = parseInt(partes[0]);
let minuto = parseInt(partes[1]);

Then simply calculate the difference in minutes between those times and at the end convert this difference in minutes to the equivalent in hours and minutes. The code follows below (I have "cleaned" your HTML, removing the div's and CSS classes, just to focus on the mechanism itself):

function ajustaHorario(idCampo) {
    let valorCampo = document.getElementById(idCampo).value;
    let [hora, minuto] = valorCampo.split(':').map(v => parseInt(v));
    return (hora * 60) + minuto;
}

function calculaTotal() {
    // diferença entre horário de início e o início do intervalo
    let totalAntesIntervalo = ajustaHorario('intervaloInicio') - ajustaHorario('horarioInicio');
    // diferença entre fim do intervalo e o horário de término
    let totalDepoisIntervalo = ajustaHorario('horarioFim') - ajustaHorario('intervaloFim');
    
    // tempo total (em minutos)
    let total = totalAntesIntervalo + totalDepoisIntervalo;
    
    // quebrar o total em horas e minutos
    let totalHoras = Math.floor(total / 60);
    let totalMinutos = total % 60;
    
    // colocar o valor no campo
    document.getElementById('cargaHorariaTotal').value = totalHoras + ' horas e ' + totalMinutos + ' minutos';
}
<label for="horarioInicio"><br>Horário de início:</label>
<input type="time" id="horarioInicio" placeholder="Exemplo: 08:00" />

<label for="intervaloInicio"><br>Início do intervalo:</label>
<input type="time" maxlength="5" id="intervaloInicio" placeholder="Exemplo: 12:00" />

<label for="intervaloFim"><br>Fim do intervalo:</label>
<input type="time" maxlength="5" id="intervaloFim" placeholder="Exemplo: 13:00" />

<label for="horarioFim"><br>Horario de Término:</label>
<input type="time" maxlength="5" id="horarioFim" placeholder="Exemplo: 18:00" />

<br><label for="carga-horaria">Carga Horária Total:</label>
<input type="text" id="cargaHorariaTotal" readonly>

<br><input type="button" value="Calcular Total" onclick="calculaTotal()">


The full time load format is in text ("X hours and Y minutes"), but you can also put in other formats such as hh:mm. Just remembering that this format is for time of day, but what the total value represents is actually a duration. Those are two things you shouldn’t confuse:

  • a time represents a specific point day. Ex: break started at 11:30 (11 hours and 30 minutes, morning)
  • a duration represents a quantity of time. Ex: today I worked 8 hours and 20 minutes (I didn’t say what hours I started or finished, if I had break, none of that, it’s just the amount time, not necessarily related to a specific time)

Although they both use the same words (hours, minutes, etc), they are not the same thing. The fields input type="time" represent times, and the total that has been calculated represents a duration.

You can even write a duration of 8 hours and 20 minutes as "08:20", but should not confuse this with the "8 and 20 in the morning" time. I have chosen to write the duration as text, but if you want, you can format it as hh:mm:

document.getElementById('cargaHorariaTotal').value =
    totalHoras.toString().padStart(2, '0')
    + ':' + totalMinutos.toString().padStart(2, '0');

This code is very "naive" because it does not check if the departure time is greater than the input, for example. You can make this check by comparing the values of ajustaHorario(campo). In addition, the code only deals with schedules, so it is assumed that all schedules belong to the same day.


If the browser does not support the input type="time"

When the browser does not support the input type="time", this behaves like a common text field. But you can limit the values accepted using a pattern, in accordance with suggested in the documentation.

In the example below I put the field as text just for you to see how it would work if the field were time and the browser did not support it. But in your code I would always leave as time:

<form>
<input type="text" id="horarioInicio" placeholder="Exemplo: 08:00" required
 pattern="([01][0-9]|2[0-3]):([0-5][0-9])"/>

<input type="submit" value="submit">
</form>

Thus, the field only accepts values in the format hh:mm, hours between 00 and 23 and minutes between 00 and 59.

The pattern contains a regular expression (also called regex), indicating the format accepted in the field.

The brackets form a character class. For example, [01] means "the digit zero or the digit 1", while [0-9] is "any digit from 0 to 9".

The | means alternation, then [01][0-9]|2[0-3] means:

  • digit 0 or 1, followed by a digit from 0 to 9, or
  • digit 2, followed by a digit from 0 to 3

With that, I guarantee the hours can be from 00 to 23.

Next we have :, and finally [0-5][0-9] (a digit from 0 to 5, followed by a digit from 0 to 9), ensuring that minutes can be from 00 to 59.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.