I tried this in moment.js
moment.duration(375,'days').humanize()
and get "a year" as answer, but I would expect "a year and 10 days". Is there a way in moment.js to get the full humanized value?
I tried this in moment.js
moment.duration(375,'days').humanize()
and get "a year" as answer, but I would expect "a year and 10 days". Is there a way in moment.js to get the full humanized value?
I found this small lib, that only display duration (if you don't really need all the features of moment.js)
https://github.com/EvanHahn/HumanizeDuration.js
Moment.js is providing the fromNow
function to get time durations in human readable fromat, see http://momentjs.com/docs/#/displaying/fromnow/
Example:
moment([2007, 0, 29]).fromNow(); // 4 years ago
moment().subtract(375, 'days').fromNow(); // a year ago
You need to use third party lib as suggested by @Fluffy
I was looking at the same issue and seems like there is no plan on supporting this in the future...
Although one workaround proposed is to make an language definition that overrides default implementation of humanized messages:
https://github.com/timrwood/moment/issues/348
Kind of an overkill if you ask me...
Try this plugin:
https://github.com/jsmreese/moment-duration-format
moment.duration(123, "minutes").format("h [hrs], m [min]");
// "2 hrs, 3 min"
Use moment.relativeTimeThreshold('y', 365)
to set the rounding.
moment.relativeTimeThreshold('s', 60);
moment.relativeTimeThreshold('m', 60);
moment.relativeTimeThreshold('h', 24);
moment.relativeTimeThreshold('d', 31);
moment.relativeTimeThreshold('M', 12);
moment.relativeTimeThreshold('y', 365);
This is my solution, I like it better than the others here:
val moment1 = moment();
val moment2 = mement();
console.log(moment.duration(moment1.diff(moment2)).humanize());
i have written this javascript code to humanize the duration,
function humanizeDuration(timeInMillisecond) {
var result = "";
if (timeInMillisecond) {
if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24 * 30 * 12))) > 0) {//year
result = result === 1 ? result + " Year" : result + " Years";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24 * 30))) > 0) {//months
result = result === 1 ? result + " Month" : result + " Months";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24))) > 0) {//days
result = result === 1 ? result + " Day" : result + " Days";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60))) > 0) {//Hours
result = result === 1 ? result + " Hours" : result + " Hours";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60))) > 0) {//minute
result = result === 1 ? result + " Minute" : result + " Minutes";
} else if ((result = Math.round(timeInMillisecond / 1000)) > 0) {//second
result = result === 1 ? result + " Second" : result + " Seconds";
} else {
result = timeInMillisecond + " Millisec";
}
}
return result;
}
This is my solution on CoffeeScript:
humanizeDuration = (eventDuration)->
eventMDuration = Moment.duration(eventDuration, 'seconds');
eventDurationString = ""
if (eventMDuration.days() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.days(), 'days').humanize()
if (eventMDuration.hours() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.hours(), 'hours').humanize()
if (eventMDuration.minutes() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.minutes(), 'minutes').humanize()
eventDurationString.trim()
This issue on Github contains a lot of discussion about exactly that. Many are asking for a more precise humanized option.
Chime in with why you need it, use cases, etc.
https://github.com/moment/moment/issues/348
Based on Ihor Kaslashnikov's solution, I modified the function to be even more accurate using vanilla Javascript.
function momentHumanize(eventDuration, unit) {
var eventMDuration = moment.duration(eventDuration, unit);
var eventDurationArray = [];
if (eventMDuration.years() > 0) {
eventDurationArray.push(eventMDuration.years() + ' years');
eventMDuration.subtract(eventMDuration.years(), 'years')
}
if (eventMDuration.months() > 0) {
eventDurationArray.push(eventMDuration.months() + ' months');
eventMDuration.subtract(eventMDuration.months(), 'months')
}
if (eventMDuration.weeks() > 0) {
eventDurationArray.push(eventMDuration.weeks() + ' weeks');
eventMDuration.subtract(eventMDuration.weeks(), 'weeks')
}
if (eventMDuration.days() > 0) {
eventDurationArray.push(eventMDuration.days() + ' days');
eventMDuration.subtract(eventMDuration.days(), 'days')
}
if (eventMDuration.hours() > 0) {
eventDurationArray.push(eventMDuration.hours() + ' hours');
eventMDuration.subtract(eventMDuration.hours(), 'hours')
}
if (eventMDuration.minutes() > 0) {
eventDurationArray.push(eventMDuration.minutes() + ' minutes');
}
return eventDurationArray.length === 1 ? eventDurationArray[0] :
eventDurationArray.join(' and ')
}
This will remove any amount from the moment instance once it humanizes it.
I did this because Ihor's solution was inaccurate, given that moment's humanize function rounds the value. For example, if I had 2.8 hours, it should've been 2 hours and an hour
.
My solution removes the 2 hours, from the instance, leaving only 0.8 hours, and doesn't use moment's humanize function to avoid rounding.
Examples:
momentHumanize(45, 'minutes') // 45 minutes
momentHumanize(4514, 'minutes') // 3 days and 3 hours and 14 minutes
momentHumanize(45145587, 'minutes') // 85 years and 10 months and 1 days and 2 hours and 27 minutes