Moment: <moment 45 minutes ago>.from(moment()) // returns 'an hour ago'

Created on 7 Oct 2014  ·  4Comments  ·  Source: moment/moment

Thanks for the great library.

One issue I've run into is that from() will round durations >= 45 minutes up to an hour. Other units (seconds, days etc.) are rounded as well. In our application we'd like to be a bit more precise than this. I believe that the function listed below does the rounding. What would be an appropriate solution to optionally remove rounding? Thanks!

    function relativeTime(milliseconds, withoutSuffix, lang) {
        var seconds = round(Math.abs(milliseconds) / 1000),
            minutes = round(seconds / 60),
            hours = round(minutes / 60),
            days = round(hours / 24),
            years = round(days / 365),
            args = seconds < 45 && ['s', seconds] ||
                minutes === 1 && ['m'] ||
                minutes < 45 && ['mm', minutes] ||
                hours === 1 && ['h'] ||
                hours < 22 && ['hh', hours] ||
                days === 1 && ['d'] ||
                days <= 25 && ['dd', days] ||
                days <= 45 && ['M'] ||
                days < 345 && ['MM', round(days / 30)] ||
                years === 1 && ['y'] || ['yy', years];
        args[2] = withoutSuffix;
        args[3] = milliseconds > 0;
        args[4] = lang;
        return substituteTimeAgo.apply({}, args);
    }

Most helpful comment

You can actually set the time threshold that you want it to be set to, as seen here in the documentation.

If you always want to display the full time, you can set your thresholds to be more precise:

// Set thresholds to be at their "max" value
moment.relativeTimeThreshold('s', 59);
moment.relativeTimeThreshold('m', 59);
moment.relativeTimeThreshold('h', 23);
moment.relativeTimeThreshold('d', 28);
moment.relativeTimeThreshold('M', 12);

All 4 comments

Specifically, this can be run in order to illustrate the issue:

moment().subtract(45, 'minutes').from(moment())

You can actually set the time threshold that you want it to be set to, as seen here in the documentation.

If you always want to display the full time, you can set your thresholds to be more precise:

// Set thresholds to be at their "max" value
moment.relativeTimeThreshold('s', 59);
moment.relativeTimeThreshold('m', 59);
moment.relativeTimeThreshold('h', 23);
moment.relativeTimeThreshold('d', 28);
moment.relativeTimeThreshold('M', 12);

Great, thanks. Is there any way for me to display a 75 minute duration as 'an hour and 15 minutes', rather than 'an hour'? Same question for 90 minutes -> '2 hours'.

Ideally I'd like the string output to show the two most significant contiguous units. A few examples:

  • 1 hour, 56 minutes, 7 seconds -> 'one hour and 56 minutes'
  • 4 hours, 56 seconds -> 'four hours'
  • 2 days, 56 minutes -> 'two days'
  • 2 days, 1 hour, 1 minute -> 'two days and one hour'

Would this behavior be desired for moment.js, or does it diverge too much from the target use cases of the library?

This is the so called "duration format" which is a very, very complicated topic on its own. tl;dr its something that is not implemented in core, but here are ways to achieve what you want manually or with plugins. You can try reading: https://github.com/moment/moment/issues/1048 or directly use: https://github.com/jsmreese/moment-duration-format.

Was this page helpful?
0 / 5 - 0 ratings