diff --git a/README.md b/README.md index eaf0dfc..076942f 100644 --- a/README.md +++ b/README.md @@ -54,3 +54,8 @@ Truncates a string to length-1 and appends '…'. If string is shorter than leng ####humanize.truncatewords(string, numWords)#### Truncates a string to only include the first numWords words and appends '…'. If string has fewer words than numWords, then no-op + +####humanize.humanizeSeconds(seconds, numWords)#### +Converts seconds to other units if possible. So 24*60*60*2+120+120 seconds becomes "2 days 2 hours 2 minutes" + +The second argument can limit on how many units you want to see. The previous example with extra argument of 2 would only show 2 days 2 hours and omit the minutes part. diff --git a/humanize.js b/humanize.js index 7e6d415..12fa2c2 100644 --- a/humanize.js +++ b/humanize.js @@ -471,4 +471,69 @@ return words.slice(0, numWords).join(' ') + '…'; }; + /** + * Converts seconds to other units if possible. So + * 24*60*60*2+120+120 seconds becomes "2 days 2 hours 2 minutes" + * + * The second argument can limit on how many units you want + * to see. The previous example with extra argument of 2 would + * only show 2 days 2 hours and omit the minutes part. + * + * If any of the units is 0 then the function wont't return + * those. + */ + humanize.humanizeSeconds = function(seconds, numWords) { + if (seconds === 0) + return "0 minutes"; + + var week = Math.floor(seconds / (7 * 24 * 60 * 60)); + var weekS = (week == 1) ? " week" : " weeks"; + seconds = seconds % (7 * 24 * 60 * 60); + + var day = Math.floor(seconds / (24 * 60 * 60)); + var dayS = (day == 1) ? " day" : " days"; + seconds = seconds % (24 * 60 * 60); + + var hour = Math.floor(seconds / 3600); + var hourS = (hour == 1) ? " hour" : " hours"; + seconds = seconds % (3600); + + var min = Math.floor(seconds / 60); + var minS = (min == 1) ? " minute" : " minutes"; + seconds = seconds % (60); + + // if number of words is undefined we default + // to showing all of them, 10 is enough not to + // reach 0 :) + if (isNaN(numWords)) + numWords = 10; + + var rtrn = ""; + if (week !== 0 && numWords > 0) { + rtrn = rtrn + week + weekS + " "; + numWords--; + } + + if (day !== 0 && numWords > 0) { + rtrn = rtrn + day + dayS + " "; + numWords--; + } + + if (hour !== 0 && numWords > 0) { + rtrn = rtrn + hour + hourS + " "; + numWords--; + } + + if (min !== 0 && numWords > 0) { + rtrn = rtrn + min + minS + " "; + numWords--; + } + + // remove the trailing space + if (rtrn.length > 0) + rtrn = rtrn.substring(0, rtrn.length-1); + + return rtrn; + }; + }).call(this); diff --git a/specs/humanize.spec.js b/specs/humanize.spec.js index 6b13376..4e96015 100644 --- a/specs/humanize.spec.js +++ b/specs/humanize.spec.js @@ -410,5 +410,20 @@ describe('humanize:', function() { }); + describe('#humanizeSeconds', function() { + it('should be able to convert seconds to human readables', function() { + humanize.humanizeSeconds(0).should.equal('0 minutes'); + humanize.humanizeSeconds(60).should.equal('1 minute'); + humanize.humanizeSeconds(120).should.equal('2 minutes'); + humanize.humanizeSeconds(3600).should.equal('1 hour'); + humanize.humanizeSeconds(7200).should.equal('2 hours'); + humanize.humanizeSeconds(24*60*60).should.equal('1 day'); + humanize.humanizeSeconds(2*24*60*60).should.equal('2 days'); + humanize.humanizeSeconds(2*24*60*60 + 7200).should.equal('2 days 2 hours'); + humanize.humanizeSeconds(2*24*60*60 + 7200 + 120).should.equal('2 days 2 hours 2 minutes'); + humanize.humanizeSeconds(2*24*60*60 + 7200 + 120, 2).should.equal('2 days 2 hours'); + humanize.humanizeSeconds(2*24*60*60 + 7200 + 120, 1).should.equal('2 days'); + }); + }); });