73

これをmoment.jsで試しました

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

答えとして「1年」が得られますが、「1年と10日」と予想されます。moment.js に完全な人間化された値を取得する方法はありますか?

4

14 に答える 14

24

期間のみを表示するこの小さなライブラリを見つけました(moment.jsのすべての機能が本当に必要ない場合)

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

于 2013-09-26T09:22:23.467 に答える
11

私は同じ問題を見ていましたが、将来これをサポートする計画はないようです...

提案された回避策の 1 つは、人間化されたメッセージのデフォルトの実装をオーバーライドする言語定義を作成することです。

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

あなたが私に尋ねると、一種のやり過ぎです...

于 2012-11-13T12:22:17.483 に答える
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 に答える
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

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 時間だけを残して、丸めを避けるために瞬間の人間化関数を使用しません。

例:

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 に答える