I wrote a little function which formats a ms timestamp in a human readable way. I know there are lots of scripts out there, but I needed a very simple one, which only outputs minutes and hours.

I was wondering if there is any way to shorten or improve this code snippet, because to me it seems to be very long for the few things it actually does.

function prettyTime(ms) {
var sec = ms / 1000,
time,
timeUnit;

if(sec > 3600) {
// Hours
time = Math.round(sec / 3600);
timeUnit = ' hr';
} else if(sec > 60) {
// Minutes
time = Math.round(sec / 60);
timeUnit = ' min';
} else {
return 'less than 1 min';
}

if(time > 1) {
timeUnit += 's';
}

return 'about ' + time + timeUnit + 'remaining';
}


-
One of the scripts out there is fromNow using moment.js. –  ChrisW Mar 21 at 15:19

Hope this might be helpful -

function getRelativeTime(ms){
var SECOND_MS = 1000;
var MINUTE_MS = 60 * SECOND_MS;
var HOUR_MS = 60 * MINUTE_MS;
var DAY_MS = 24 * HOUR_MS;
var WEEK_MS = 7 * DAY_MS;
var MONTH_MS = 30 * DAY_MS;

var lookup = ["months", "weeks", "days", "hours", "minutes", "seconds"];
var values = [];
values.push(ms / MONTH_MS); ms %= MONTH_MS;
values.push(ms / WEEK_MS); ms %= WEEK_MS;
values.push(ms / DAY_MS); ms %= DAY_MS;
values.push(ms / HOUR_MS); ms %= HOUR_MS;
values.push(ms / MINUTE_MS); ms %= MINUTE_MS;
values.push(ms / SECOND_MS); ms %= SECOND_MS;

for(var i=0 ; i <values.length; i++){
var val = Math.round(values[i]);
if(val <= 0) continue;

pretty += val + " " + lookup[i] + " ago";
break;
}
return pretty;
}

getRelativeTime(10000);


Output :

about 10 seconds ago


You can easily customize above code for your "xx hours and xx mins ago" use-case. Just change the for loop like this -

for(var i=0 ; i <values.length; i++){
var val = Math.round(values[i]);
if(val <= 0) continue;

pretty += val + " " + lookup[i];

var nextval = Math.round(values[i+1]);
if(i+1 < values.length && nextval > 0){
pretty += " and " + nextval + " " + lookup[i+1] + " ago";
}
else {
pretty += " ago";
}
break;
}


Output

getRelativeTime(100000);

about 2 minutes and 40 seconds ago


getRelativeTime(1000000);

about 17 minutes and 40 seconds ago


UPDATE:

Math.round is causing wrong result in above code, Math.floor is more appropriate.

-
Thanks, that looks a lot cleaner to me, although I think var SECOND = 1; should be var SECOND = 1000;, shouldn't it? Is there any elegant way to use 'less than a minute ago' instead of seconds? –  demrks Mar 17 at 23:48
You're right, updated the code. –  Kevindra Mar 17 at 23:54
IMO, SECOND, MINUTE, etc. should be named SECOND_MS, MINUTE_MS, and so on so it's clear what units they're in. –  jamesdlin Mar 18 at 1:37
Makes sense, you got it! –  Kevindra Mar 18 at 20:14
(new Date).clearTime()
.toString('H:mm')


Not identical but will get you closer with less code using datejs

-
-1 That answer explicitly says that datejs is outdated. –  RoToRa Mar 20 at 23:57
My mistake. Moment js is the new recommendation –  Luc Mar 21 at 0:02