views:

305

answers:

5

I'm having trouble calculating a time (hours:minutes) difference between three time values presented as HH:mm strings.

I'm calculating time worked in a day from time in, lunch time and time out.

e.g. var time_worked = time_out - lunch - time_in or 07:00 = 17:00 - 01:00 - 09:00

I'm familiar with the php dates but the javascript date object is scary!

Code:

var time_in = $(".time-in").val(); // 09:00
var time_out = $(".time-out").val(); // 17:00
var lunch = $(".lunch").val(); // 01:00

var time = time_out - lunch - time_in; // should be 07:00 or 7  
+3  A: 

I'd suggest thinking about this slightly differently...given your three times, convert all times into pure hours, then do the math as you would in hours. If you need, you can turn the fractional hours back into minutes.

Any time can be turned into hours just by dividing the number of minutes by 60 and adding the result to the hours portion. Your math then gets very easy, it's the same expression you have except you don't have to do time based math.

If you're given an input of something of the form "hh:mm" where hh and mm are integers then you can compute pure hours using the following expression:

var mytime = "hh:mm";
var temp = mytime.split(":");
var hours = temp[0] + (temp[1]/60);

edit: Others have noted problems occurring if you deal with a night shift. A simple solution (not requiring creation of Date objects) is to add 24 hours to the start time when the end time is less than the start time (and that of course can be done in the "pure hours" domain).

Mark E
Thanks, I've definitely had my blinkers on the last few hours! That makes a lot more sense.
th3hamburgler
+2  A: 

I am not enough of a JavaScript expert to help you there but since you seem to be using relitive times, if your place works 24 hours, pay special attention to any shift that crosses midnight. 7:00 Thursday - 23:00 Wednesday = 8.

fupsduck
good point.. if the times are represented with Date objects, it's probably a better idea to convert all to epoch and make calculations..
Anurag
yeah, none of the time fields are directly linked to a date, so converting them to date objects is gonna cause problems.For this application, converting the string to decimal hour values will be a better method.
th3hamburgler
of course you're assuming that the day information is available. assuming only the information the OP has revealed, a simple solution is to check if the start time is larger than the end time, and if it is to add 24 hours to the end time.
Mark E
+2  A: 

Use the getTime() function, which returns number of milliseconds since Jan 1, 1970. So your code would look like:

var time_worked_ms = time_out.getTime() - lunch.getTime() - time_in.getTime();

time_worked_ms would contain the number of milliseconds for your interval.

mlsteeves
A: 

Given 2 "HH:mm" strings, the following method will return a float number of the time between them:

function timeDiff(time1, time2) {
    var time1array = time1.split(":");
    var time2array = time2.split(":");
    var hour1 = parseInt(time1array[0]);
    var min1 = parseInt(time1array[1]);
    var hour2 = parseInt(time2array[0]);
    var min2 = parseInt(time2array[1]);
    return (hour1 + min1/60) - (hour2 + min2/60);
}
Kaleb Brasee
+2  A: 

I think you're misconceptualizing your problem domain.

Specifically, if you're trying to find timeAtWork, and everything is represented as a time object (e.g. in seconds since epoch), there are FOUR important times here you need to know (the three you listed [startWork, endWork and startLunch] and the one you missed, [endLunch]). In that case, you can calculate your desired value by the following subtractions, assuming that whatever language you're working in supports adding/subtracting dates (for JavaScript, look at the excellent date.js library)

timeAtWork = (endWork-endLunch) + (startLunch-startWork)

or equivelantly

timeAtWork = (endWork - startWork) - (endLunch - startLunch)

However, it sounds to me like you have two 'time' variables [startWork and endWork] and one 'timespan' variable [lunchDuration]. In this case, lunchDuration is something like 3600 (one hour), but does not represent a true date/time combination.

In that case, lunchDuration === (endLunch - startLunch), so you can calculate timeAtWork as follows:

timeAtWork = (endWork - startWork) - lunchDuration

Hope this helps!

linked