これをmoment.jsで試しました
moment.duration(375,'days').humanize()
答えとして「1年」が得られますが、「1年と10日」と予想されます。moment.js に完全な人間化された値を取得する方法はありますか?
これをmoment.jsで試しました
moment.duration(375,'days').humanize()
答えとして「1年」が得られますが、「1年と10日」と予想されます。moment.js に完全な人間化された値を取得する方法はありますか?
期間のみを表示するこの小さなライブラリを見つけました(moment.jsのすべての機能が本当に必要ない場合)
私は同じ問題を見ていましたが、将来これをサポートする計画はないようです...
提案された回避策の 1 つは、人間化されたメッセージのデフォルトの実装をオーバーライドする言語定義を作成することです。
https://github.com/timrwood/moment/issues/348
あなたが私に尋ねると、一種のやり過ぎです...
この正確な問題を解決する関数を作成しました。
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 フィルターとして使用しています。
これは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()
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