73

我在 moment.js 中试过这个

moment.duration(375,'days').humanize()

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

4

14 回答 14

42

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 的建议使用第三方库

于 2015-07-02T14:01:33.447 回答
24

我找到了这个只显示持续时间的小库(如果你真的不需要 moment.js 的所有功能)

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

于 2013-09-26T09:22:23.467 回答
12

试试这个插件:

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

moment.duration(123, "minutes").format("h [hrs], m [min]");
// "2 hrs, 3 min"
于 2014-05-22T07:24:55.213 回答
11

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

尽管提出的一种解决方法是创建一个覆盖人性化消息的默认实现的语言定义:

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

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

于 2012-11-13T12:22:17.483 回答
7

用于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);
于 2017-10-10T12:53:50.223 回答
3

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

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 过滤器来正确地人性化持续时间。

于 2020-05-07T21:43:42.100 回答
2

Github 上的这个问题包含很多关于这一点的讨论。许多人要求更精确的人性化选择。

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

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

于 2017-04-12T16:34:02.550 回答
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;
}
于 2017-05-19T05:19:30.553 回答
1

解决方案之一:

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 没有说明开始日期。将时间段拆分为多个部分,添加“天”/“小时”/... 是显而易见的。

于 2019-05-28T12:02:38.060 回答
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);

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

于 2021-01-07T12:28:15.730 回答
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()
于 2015-09-17T10:38:57.263 回答
-2

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

val moment1 = moment();
val moment2 = mement();
console.log(moment.duration(moment1.diff(moment2)).humanize());
于 2017-08-22T22:48:52.610 回答
-2

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

一旦它人性化,这将从时刻实例中删除任何数量。我这样做是因为 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
于 2018-11-02T10:29:45.130 回答
-3

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

document.write(s)

在此处输入链接描述

于 2020-03-19T12:49:30.940 回答