简体   繁体   中英

How to get duration in weeks with Moment.js?

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/

Use the new 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.

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, ie 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"

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 technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM