在moment.js中完全人性化的持续时间

时间:2012-07-02 19:54:40

标签: momentjs

我在moment.js

尝试了这个
moment.duration(375,'days').humanize()

并获得“一年”作为答案,但我希望“一年零十天”。在moment.js中有没有办法获得完整的人性化价值?

14 个答案:

答案 0 :(得分:19)

Moment.js提供了fromNow函数来获取人类可读时间的持续时间,请参阅http://momentjs.com/docs/#/displaying/fromnow/

示例:

moment([2007, 0, 29]).fromNow(); // 4 years ago
moment().subtract(375, 'days').fromNow(); // a year ago

您需要使用@Fluffy

建议的第三方库

答案 1 :(得分:18)

我发现这个小lib,只显示持续时间(如果你真的不需要moment.js的所有功能)

https://github.com/EvanHahn/HumanizeDuration.js

答案 2 :(得分:9)

我在看同样的问题,似乎没有计划在未来支持这个......

虽然提出的一种解决方法是使语言定义覆盖人性化消息的默认实现:

https://github.com/timrwood/moment/issues/348

如果你问我,有点矫枉过正......

答案 3 :(得分:9)

试试这个插件:

https://github.com/jsmreese/moment-duration-format

moment.duration(123, "minutes").format("h [hrs], m [min]");
// "2 hrs, 3 min"

答案 4 :(得分:5)

使用moment.relativeTimeThreshold('y', 365)设置舍入。

moment.relativeTimeThreshold('s', 60);
moment.relativeTimeThreshold('m', 60);
moment.relativeTimeThreshold('h', 24);
moment.relativeTimeThreshold('d', 31);
moment.relativeTimeThreshold('M', 12);
moment.relativeTimeThreshold('y', 365);

答案 5 :(得分:1)

Github上的

This issue包含了很多关于这一点的讨论。许多人要求更精确的人性化选择。

请说明您需要它的原因,用例等。

https://github.com/moment/moment/issues/348

答案 6 :(得分:1)

我已经编写了这个javascript代码来人性化持续时间,

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;
}

答案 7 :(得分:1)

这是我的解决方案,我比其他人更喜欢它:

val moment1 = moment();
val moment2 = mement();
console.log(moment.duration(moment1.diff(moment2)).humanize());

答案 8 :(得分:1)

我做了一个函数来解决这个确切的问题。

function formatDuration(period) {
    let parts = [];
    const duration = moment.duration(period);

    // return nothing when the duration is falsy or not correctly parsed (P0D)
    if(!duration || duration.toISOString() === "P0D") return;

    if(duration.years() >= 1) {
        const years = Math.floor(duration.years());
        parts.push(years+" "+(years > 1 ? "years" : "year"));
    }

    if(duration.months() >= 1) {
        const months = Math.floor(duration.months());
        parts.push(months+" "+(months > 1 ? "months" : "month"));
    }

    if(duration.days() >= 1) {
        const days = Math.floor(duration.days());
        parts.push(days+" "+(days > 1 ? "days" : "day"));
    }

    if(duration.hours() >= 1) {
        const hours = Math.floor(duration.hours());
        parts.push(hours+" "+(hours > 1 ? "hours" : "hour"));
    }

    if(duration.minutes() >= 1) {
        const minutes = Math.floor(duration.minutes());
        parts.push(minutes+" "+(minutes > 1 ? "minutes" : "minute"));
    }

    if(duration.seconds() >= 1) {
        const seconds = Math.floor(duration.seconds());
        parts.push(seconds+" "+(seconds > 1 ? "seconds" : "second"));
    }

    return "in "+parts.join(", ");
}

此函数采用句点字符串(ISO 8601),用Moment(> 2.3.0)对其进行解析,然后对于每个时间单位,将字符串推入parts数组中。然后,parts数组中的所有内容都与", "一起连接为分隔字符串。

您可以在这里进行测试:https://jsfiddle.net/mvcha2xp/6/

我将其用作Vue过滤器以正确地使持续时间人性化。

答案 9 :(得分:0)

这是我在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()

答案 10 :(得分:0)

一种解决方案:

function getCountdown() {
  // diff in seconds, comes through function's params
  const diff = 60*60*24*4 + 60*60*22 + 60*35 + 5;
  const MINUTE = 60;
  const HOUR = MINUTE * 60;
  const DAY = HOUR * 24;

  const days = Math.floor(diff / DAY);
  const hDiff = diff % DAY;
  const hours = Math.floor(hDiff / HOUR);
  const mDiff = hDiff % HOUR;
  const minutes = Math.floor(mDiff / MINUTE);
  const seconds = mDiff % MINUTE;

  return [days, hours, minutes, seconds]
    .map(v => (''+v)[1] ? ''+v : '0'+v)
}


output: ["04", "22", "35", "05"]

我最多只需要几天,但是可以很容易地延长到几周。 自从diff没说开始日期以来,几个月就没有意义了。 将期间分为多个部分,显然可以加上“天” /“小时” /...。

答案 11 :(得分:0)

Moment.js 提供:

var y = moment.duration(375,'days').years(); // returns 1
var d = moment.duration(375,'days').days(); // returns 9

var data = y + 'y ' + d + 'd';

console.log(data);

这可以与一些额外的逻辑一起使用

答案 12 :(得分:-1)

基于Ihor Kaslashnikov的解决方案,我使用香草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 ')
}

一旦实例化,它将立即删除实例中的所有金额。 我这样做是因为考虑到瞬间的人性化功能使价值四舍五入,所以Ihor的解决方案不准确。例如,如果我有2.8个小时,应该是2 hours and an hour。 我的解决方案从实例中删除了2个小时,只剩下0.8个小时,并且不使用moment的人性化功能来避免舍入。

示例:

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

答案 13 :(得分:-1)

var s=moment([2020, 03, 29]).subtract(3, 'days').fromNow(); 

document.write(s)

enter link description here