-1

I am new with JavaScript and I am building a simple app to calculate my worked hours at work.

When I am subtracting two dates - it works fine (the result is 1:30, for example), but as soon as I add the third date it has a strange behavior and the result is +1 added hour and minutes are 59 44 29 14 (always -1 minute , while the third date itself is always a 0,15,30,45 minutes). I assume the +1 added hour is -1,but it was converted to an absolute number by Date().

Video link to the problem : https://youtu.be/EyhaVgwxOpw

CodePen : https://codepen.io/anon/pen/PLNqMa

Code

 var startHr,
    startMin,
    endHr,
    endMin,
    pause;

$(".start,.end,.pochivka").change(function () {
     startHr = Number($('#starthr').children("option:selected").val());
     startMin = Number($('#startmin').children("option:selected").val());
     endHr = Number($('#endhr').children("option:selected").val());
     endMin = Number($('#endmin').children("option:selected").val());
     pause = Number($('#pause').children("option:selected").val());

});
$(".calculate").click(function(){

    // Refer to starting hours and ending hours which get their value from chosen fields
    var secondTime = startHr + ":" + startMin +":00";
    var firstTime = endHr + ":" + endMin + ":00";
    // breakTime also gets from the same place, but has strange behaviour
    var breakTime = "00:" + pause + ":00";
    console.log(breakTime);

    let startHour = new Date().setHours(...(firstTime.split(":")));
    let endHour = new Date().setHours(...(secondTime.split(":")));
    let removeBreakHours = new Date().setHours(...(breakTime.split(":")));

    // Disable next line (and enable the code with next comments)
    // to see how normal it works without the bug 
    // Maybe it happens because I have 2 subtractions?
    let finalHours = new Date(startHour - endHour - removeBreakHours);

    // Now enable next line.It is the code without "Break times remove"
    // let finalHours = new Date(startHour - endHour);

    // ------------ 
    var workedHours = finalHours.getUTCHours() +":"+ finalHours.getUTCMinutes();
    $('.workHours').text(workedHours);

})
Berin Aptula
  • 234
  • 1
  • 12
  • 3
    You are diving in a mess about re-inventing the wheel. I strongly suggest you to look for a [timepicker plugin](https://www.google.com/search?q=jquery+timepicher&oq=jquery+timepicher&aqs=chrome..69i57j0l5.5551j0j7&sourceid=chrome&ie=UTF-8) of your choice, then use [moment.js](http://momentjs.com/) to perform the math... --- That is if you really want to have something perfectly working quite fast. Else, you also may want to dive in that mess for learning purposes... And that would be another thing. – Louys Patrice Bessette Mar 01 '19 at 22:49
  • Your code is not subtracting `Date`s, `.setHours()` returns a `Number` – P Varga Mar 01 '19 at 22:50
  • In this case, since you're not using any dates, I recommend not using `new Date` and just calculating the hours and minutes directly. See [finding the time difference between two 'time' strings without involving date](https://stackoverflow.com/questions/42908193/javascript-finding-the-time-difference-between-two-time-strings-without-invol). – showdev Mar 01 '19 at 22:55
  • @chiliNUT: Why not! I found that crazy interesting to understand the issue. And that is a considerable effort form OP. (While, I agree... The video may not last for eternity -- As this question anyway... ). – Louys Patrice Bessette Mar 01 '19 at 22:57

1 Answers1

0

I've made it working by adding the breaktime as negative minutes

$(".calculate").click(function(){

    // Refer to starting hours and ending hours which get their value from chosen fields
    var secondTime = startHr + ":" + startMin +":00";
    var firstTime = endHr + ":" + endMin + ":00";

    let startHour = new Date().setUTCHours(...(firstTime.split(":")));
    let endHour = new Date().setUTCHours(...(secondTime.split(":")));

    let finalHours = new Date(startHour - endHour);
    finalHours.setMinutes(- +pause);

    // ------------ 
    var workedHours = finalHours.getUTCHours() +":"+ finalHours.getUTCMinutes();
    $('.workHours').text(workedHours);
})

In your example you were subtracting milisseconds (to be precise miliseconds passed since 1st of Jan 1970 UTC), so I guess when JS rounds the results is rounding to lower value, resulting in 1 less minute than expected. But I haven't proved it.

JavierFromMadrid
  • 621
  • 9
  • 21