# JavaScript function for printing a countdown

As part of my project, a game, I have progress bars with countdown timers. These are updated every 250ms, to keep a relatively smooth animation if the countdown time is short.

Here's my function:

var time_format = function(time) {
var elms, names, ret, i, n;
elms = [
time / 29030400,
time / 2419200 % 12,
time / 604800 % 4,
time / 86400 % 7,
time / 3600 % 24,
time / 60 % 60,
time % 60
];
names = "yr mo w d h m s".split(" ");
ret = [];
for( i=0; i<elms.length; i++) {
n = Math.floor(elms[i]);
if( n) ret.push(n+names[i]);
}
ret = ret.join(" ");
if( ret == "") ret = "0s";
return ret;
};


I'm just wondering if any optimisations can be made to this code. There may be up to ten progress bars on a single page (after that data is paginated). My main concern is that Math.floor call, is there a faster way to floor a number?

• You cand use n = elms[i] >> 0. Bit operations are faster. – gabitzish Jan 26 '12 at 13:28

Try this:

var time_format = (function() {

var names = "yr mo w d h m s".split(" ");

return function(time) {
var elms, ret, i, n;
elms = [
time / 29030400,
time / 2419200 % 12,
time / 604800 % 4,
time / 86400 % 7,
time / 3600 % 24,
time / 60 % 60,
time % 60
];
ret = [];
for( i=0; i<elms.length; i++) {
n = elms[i];
n = n | n;
if( n) ret.push(n+names[i]);
}
ret = ret.join(" ");
if( ret == "") ret = "0s";
return ret;
}
}());


It moves the array initialization out of the function and into a closure so it's only evaluated once.

And, it uses a faster way to do the floor operation. See this article for different ways to do floor and their timing.

• Would n = elms[i] ^ 0; work too? I've seen that one used in a few places. – Niet the Dark Absol Jan 25 '12 at 6:21
• @Kolink - It seems to work. To characterize it's performance, you'd have to set up a test to measure the speed vs. the other options. – jfriend00 Jan 25 '12 at 6:31