I use moment.js
to format durations in human readable format.
For example (d
is a Date
object):
moment(d).subtract("days", 3).from(d) // returns "3 days ago"
Now I would like to get "2 weeks ago" but the code below returns the durations in days
moment(d).subtract("weeks", 2).from(d) // returns "14 days ago" i/o "2 weeks ago"
How can I get "2 weeks ago" with moment.js
?
You can do this pretty easily with a custom callback function.
moment.relativeTime.dd = function (number) {
// round to the closest number of weeks
var weeks = Math.round(number / 7);
if (number < 7) {
// if less than a week, use days
return number + " days";
} else {
// pluralize weeks
return weeks + " week" + (weeks === 1 ? "" : "s");
}
}
http://jsfiddle.net/timrwood/sWsXQ/
updateLocale()
.Moment.js has been updated again so the preferred method is the following:
moment.updateLocale('en', {
relativeTime : {
future: 'in %s',
past: '%s ago',
s: 'a few seconds',
m: 'a minute',
mm: '%d minutes',
h: 'an hour',
hh: '%d hours',
d: 'a day',
dd: function(number) {
if (number < 7) {
return number + ' days'; // Moment uses "d" when it's just 1 day.
}
else {
var weeks = Math.round(number / 7);
return weeks + ' ' + (weeks > 1 ? 'weeks' : 'week');
}
},
M: 'a month',
MM: '%d months',
y: 'a year',
yy: '%d years'
}
});
Thanks to @timrwood and @gahen for their answers.
I'm in the works to get Moment updated so that you can override just a single relativeTime
object, like dd
, instead of having to provide all of the objects.
The GitHub Issue is here, so give it a thumbs up if you'd like to do something like this instead:
moment.updateLocale('en', {
relativeTime : {
dd: function(number) {
if (number < 7) {
return number + ' days'; // Moment uses "d" when it's just 1 day.
}
else {
var weeks = Math.round(number / 7);
return weeks + ' ' + (weeks > 1 ? 'weeks' : 'week');
}
}
}
});
I can't comment on the previous answer but I wanted to leave an updated answer (based on timrwood's)
moment.locale('en', {
relativeTime : {
future: "in %s",
past: "%s ago",
s: "seconds",
m: "a minute",
mm: "%d minutes",
h: "an hour",
hh: "%d hours",
d: "a day",
dd: function (number) {
var weeks = Math.round(number / 7);
if (number < 7) {
// if less than a week, use days
return number + " days";
} else {
// pluralize weeks
return weeks + " week" + (weeks === 1 ? "" : "s");
}
},
M: "a month",
MM: "%d months",
y: "a year",
yy: "%d years"
}
});
$window.moment.relativeTimeThreshold('d', 340); // if you want weeks instead of months, otherwise put a 28 or so.
improving on @vinjenzo's answer, when you need date diff in weeks, you will most likely encounter days returned:
var aPastDate = moment().subtract(5,'months');
var aPastDay = moment().subtract(6,'days');
var now = moment();
moment.fn.durationInWeeks = function(fromDate, toDate) {
var days = toDate.diff(fromDate, 'days');
var weeks = toDate.diff(fromDate, 'weeks');
if (weeks === 0) {
return days + ' ' + (days > 1 ? 'days' : 'day');
} else {
return weeks + ' ' + (Math.round(days / 7) > 1 ? 'weeks' : 'week');
}
}
moment().durationInWeeks(aPastDate,now); // 21 weeks
moment().durationInWeeks(aPastDay,now); // 6 days
The documentation lists the rules for creating those strings (under "Humanize time from another moment"). While you can modify the strings by changing moment.relativeTime
, this is limited to the text that is displayed around the number, i.e. you can't change days to weeks.
You'll have to extend moment.js
or write some custom code to implement this functionality.
sharing and hoping still useful:
var aPastDate = moment().subtract(5,'months');
var now = moment();
moment.fn.durationInWeeks = function (fromDate, toDate) {
var weeks = toDate.diff( fromDate, 'weeks' );
return weeks + ' weeks ago'; //your own format
}
moment().durationInWeeks(aPastDate,now);
//"21 weeks ago"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With