javascript - How to format duration as XX hours and YY minute(s) - Stack Overflow

I have a given duration in minutes, e.g. 100 minutes, 140 minutes.I need to display them in "XX h

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

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

Share Improve this question edited Mar 10, 2023 at 15:28 Mr. Polywhirl 48.9k12 gold badges94 silver badges145 bronze badges asked Mar 10, 2023 at 14:07 eXceptioneXception 2,3413 gold badges19 silver badges35 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

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

To convert a duration given in minutes to the format "XX hours and YY minute(s)", you can use the following algorithm:

Calculate the number of hours in the duration by dividing the duration in minutes by 60 and taking the integer part of the result. For example, if the duration is 140 minutes, then the number of hours is 140/60 = 2.

Calculate the number of remaining minutes after subtracting the hours from the total duration by taking the remainder of the previous division. For example, if the duration is 140 minutes and we have already calculated that there are 2 hours, then the number of remaining minutes is 140 % 60 = 20.

Format the result using the following pattern: "XX hours and YY minute(s)". If there are no hours, then omit the "hours" part. If there are no minutes, then omit the "minute(s)" part. For example, if the duration is 140 minutes, then the result should be "2 hours and 20 minutes".

Example Program For This Algorith:

function formatDuration(duration) {
  const hours = Math.floor(duration / 60);
  const minutes = duration % 60;
  if (hours === 0) {
    return `${minutes} minute${minutes !== 1 ? 's' : ''}`;
  } else if (minutes === 0) {
    return `${hours} hour${hours !== 1 ? 's' : ''}`;
  } else {
    return `${hours} hour${hours !== 1 ? 's' : ''} and ${minutes} minute${minutes !== 1 ? 's' : ''}`;
  }
}

console.log(formatDuration(1)); // output: 1 minute
console.log(formatDuration(100)); // output: 1 hour and 40 minutes
console.log(formatDuration(141)); // output: 2 hours and 21 minutes

A simple solution

const totalMinutes = 140;

const minutes = totalMinutes % 60;
const hours = (totalMinutes - minutes) / 60

const s1 = `${totalMinutes} => ${hours} hour${hours>1?'s':''} and `
const s2 = `${minutes} minute${minutes>1?'s':''}`
console.log(hours>0?s1+s2:s2)

You have contradicted yourself on the format

  1. You refer to "XX hours and YY minute(s)" but then you use single-digit numbers, in your examples.

  2. Presumably you want "hours" and not "hour" for multiple hours?

Here is my version of doing this.

function amountToTimeFormat(minutes) {
  const _hours = Math.floor(minutes / 60);
  const _mins = minutes % 60;
  
  let resHour = _hours.toString().padStart(2, '0');
  let resMin = _mins.toString().padStart(2, '0');
  
  resHour = resHour > 0 ? resHour+' hours':'';
  resMin = resMin > 0 ? resMin+' minutes':'';
  return `${resHour} ${resMin}`;
}

console.log(amountToTimeFormat(60))
console.log(amountToTimeFormat(141))
console.log(amountToTimeFormat(100))

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745474916a4629302.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信