I have a given duration in minutes, e.g. 100 minutes, 140 minutes.
I need to display them in "XX hours and YY minute(s)" format.
e.g.:
1 minutes -> 1 minute
100 minutes -> 1 hour and 40 minutes
141 minutes -> 2 hour and 21 minutes
I'd prefer to do that with date-fns or a plain JS.
Thank you
No need for date-fns, or any library for that manner.
Your browser supports formatting time, date, and duration with i18n.
const divMod = (n, m) => [Math.floor(n / m), n % m];
const createDurationFormatter = (locale, unitDisplay = 'long') => {
const
timeUnitFormatter = (locale, unit, unitDisplay) =>
Intl.NumberFormat(locale, { style: 'unit', unit, unitDisplay }).format,
fmtHours = timeUnitFormatter(locale, 'hour', unitDisplay),
fmtMinutes = timeUnitFormatter(locale, 'minute', unitDisplay),
fmtList = new Intl.ListFormat(locale, { style: 'long', type: 'conjunction' });
return (minutes) => {
const [hrs, mins] = divMod(minutes, 60);
return fmtList.format([
hrs ? fmtHours(hrs) : null,
mins ? fmtMinutes(mins) : null
].filter(v => v !== null));
}
};
let durationFormatterEn = createDurationFormatter('en-US');
console.log(durationFormatterEn(1)); // 1 minute
console.log(durationFormatterEn(100)) // 1 hour and 40 minutes
console.log(durationFormatterEn(141)) // 2 hours and 21 minutes
let durationFormatterEs = createDurationFormatter('es-US');
console.log(durationFormatterEs(1)); // 1 minuto
console.log(durationFormatterEs(100)) // 1 hora y 40 minutos
console.log(durationFormatterEs(141)) // 2 horas y 21 minutos
let durationFormatterEn2 = createDurationFormatter('en-US', 'short');
console.log(durationFormatterEn2(1)); // 1 min
console.log(durationFormatterEn2(100)) // 1 hr and 40 min
console.log(durationFormatterEn2(141)) // 2 hr and 21 min
.as-console-wrapper { top: 0; max-height: 100% !important; }
A more robust solution would be requiring milliseconds and formatting up to days:
const divMod = (n, m) => [Math.floor(n / m), n % m];
const createDurationFormatter = (locale, unitDisplay = 'long') => {
const
timeUnitFormatter = (locale, unit, unitDisplay) =>
Intl.NumberFormat(locale, { style: 'unit', unit, unitDisplay }).format,
fmtDays = timeUnitFormatter(locale, 'day', unitDisplay),
fmtHours = timeUnitFormatter(locale, 'hour', unitDisplay),
fmtMinutes = timeUnitFormatter(locale, 'minute', unitDisplay),
fmtSeconds = timeUnitFormatter(locale, 'second', unitDisplay),
fmtMilliseconds = timeUnitFormatter(locale, 'millisecond', unitDisplay),
fmtList = new Intl.ListFormat(locale, { style: 'long', type: 'conjunction' });
return (milliseconds) => {
let days, hours, minutes, seconds;
[days, milliseconds] = divMod(milliseconds, 864e5);
[hours, milliseconds] = divMod(milliseconds, 36e5);
[minutes, milliseconds] = divMod(milliseconds, 6e4);
[seconds, milliseconds] = divMod(milliseconds, 1e3);
return fmtList.format([
days ? fmtDays(days) : null,
hours ? fmtHours(hours) : null,
minutes ? fmtMinutes(minutes) : null,
seconds ? fmtSeconds(seconds) : null,
milliseconds ? fmtMilliseconds(milliseconds) : null
].filter(v => v !== null));
}
};
let durationFormatter = createDurationFormatter('en-US');
console.log(durationFormatter(6e4)); // 1 minute
console.log(durationFormatter(6e6)); // 1 hour and 40 minutes
console.log(durationFormatter(846e4)); // 2 hour and 21 minutes
console.log(durationFormatter(154849e3)); // 1 day, 19 hours, and 49 seconds
.as-console-wrapper { top: 0; max-height: 100% !important; }