Question

Having a tiny issue with a script I wrote, it's supposed to return the duration (execution time) of the script in a hh:mm:ss format.

Here is the script:

var start = new Date();
{ 

CODE GOES IN HERE

}
var end = new Date();
var miliseconds = end - start;
function runTime(ms) {
var seconds = 0;
var minutes = 0;
var hours = 0;
if (ms > 1000) {
    seconds = (ms / 1000).toFixed(0);
    if (seconds > 60) {
        seconds -= 60;
        minutes = (seconds / 60).toFixed(0);
        if (minutes > 60) {
            minutes -= 60;
            hours = (minutes / 60).toFixed(0)
        }
    }
}
if (seconds.toString().length == 1) {
    var seconds = '0' + seconds;
}   
if (minutes.toString().length == 1) {
    var minutes = '0' + minutes;
}
if (hours.toString().length == 1) {
    var hours = '0' + hours;
}   
return("Job Done in: " + hours + ":" + minutes + ":" + seconds + "(" + miliseconds + "ms)");
 }
iimDisplay(runTime(miliseconds));

These are some sample outputs :

Job Done in: 03:166:13548(13608024ms)
Job Done in: 00:51:3032(3091973ms)
Job Done in: 00:02:3706(3766265ms)
Job Done in: 00:50:2994(3053675ms)
Job Done in: 00:52:30(3152527ms)

As you can see sometimes it doesn't look quite right, usually the script is on for 40-60 minutes so the minutes are accurate most of the time.

Was it helpful?

Solution

I think your problem is here:

if (seconds > 60) {
    seconds -= 60;
    minutes = (seconds / 60).toFixed(0);
    if (minutes > 60) {
        minutes -= 60;
        hours = (minutes / 60).toFixed(0)
    }
}

When seconds is greater than 60, you just take 60. If seconds is 189, for example, you'll get 129 instead of 9, which is what you want. You've got to calculate the minutes, then do:

seconds = seconds - (minutes * 60);

You've got to do the same with minutes, but taking hours.

OTHER TIPS

if (seconds > 60) {
    seconds -= 60;

What if seconds is much larger than 60? Subtracting it only once will not be enough. What you want is

      seconds %= 60;

And same thing for the minutes.

Btw, instead of .toFixed(0) you should just use Math.floor().

Here's a formula that will make you're life easier:

hours = (ms / (1000*60*60));
ms = ms % (1000*60*60)
minutes = ms / (1000*60)
ms = ms % (1000*60)
seconds = ms / (1000)

While other posters have pointed out obvious mathamathical flaws in the @traxs original code, I wonder is it worth pointing out Timer functions in Javascript (I'm looking at you setTimeout and setInterval) can give unexpected results.

var fireCount = 0;
var start = new Date;
var timer = setInterval(function() {
  if (new Date - start > 1000) { 
    clearInterval(timer); console.log(fireCount); return;
  }
  fireCount++;
}, 0);

Three sample runs of this code: (in safari 6.1.1 on OSX 10.8.5):

  228
  227
  220

(Firefox 27.01 on OSX 10.7.5):

  250
  250
  249

You can read more about timers in Javascript: at this John Resig Blogpost Or Trevor Burnham's excellent "Async JavaScript" is well worth a read.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top