HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Output human readable time

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
humanreadableoutputtime

Problem

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 + 'ago';
}

alert(prettyTime(7600001));

Solution

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;

    var pretty = "about "; 
    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  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.

Code Snippets

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;

    var pretty = "about "; 
    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);
about 10 seconds ago
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;
}
about 2 minutes and 40 seconds ago
about 17 minutes and 40 seconds ago

Context

StackExchange Code Review Q#44623, answer score: 9

Revisions (0)

No revisions yet.