Source

durationFormat.ts


/**
 * format duration by template `format`
 * @param {number} seconds=0 seconds of duration
 * @param {string} format='hh小时mm分钟ss秒' output template
 *  hh will be replaced by hours value,
 *  mm will be replaced by minutes value
 *  ss will be replaced by seconds value
 * @param {boolean} withLeadingZero=false if `x`(e.g hours) value less than 9, then return 0x, e.g 02
 * @param {boolean} keepZeroPlace=false if `x`(e.g hours) value is 0, don't return default
 * @returns {string}
 * 
 * @example
 * durationFormat(43875); // 12小时11分钟15秒
 * durationFormat(43875, 'hh:mm:ss', true, true); // 12:11:15
 */
function durationFormat(
  seconds = 0,
  format = 'hh小时mm分钟ss秒',
  withLeadingZero = false,
  keepZeroPlace = false
) {
  const totalSeconds = Number(seconds);
  const lowerFormat = String(format).toLowerCase(); // case ignore
  const isNotNumber = Number.isNaN(totalSeconds) || typeof totalSeconds !== 'number';
  if (isNotNumber) {
    throw new TypeError('Param seconds for function durationFormat must be a number');
  }
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const secondsRest = totalSeconds - (hours * 3600) - (minutes * 60);
  const hoursReg = /hh/i;
  const minutesReg = /mm/i;
  const secondsReg = /ss/i;
  const formatWithoutHours = lowerFormat.slice(lowerFormat.indexOf('mm'));
  const formatWithoutHoursAndMinutes = lowerFormat.slice(lowerFormat.indexOf('ss'));
  const onlySeconds = hours === 0 && minutes === 0;
  const hoursStr = withLeadingZero ? addZeroBeforeNum(hours) : hours;
  const minutesStr = withLeadingZero ? addZeroBeforeNum(minutes) : minutes;
  const secondsStr = withLeadingZero ? addZeroBeforeNum(secondsRest) : secondsRest;
  if (keepZeroPlace) {
    return lowerFormat
      .replace(hoursReg, hoursStr)
      .replace(minutesReg, minutesStr)
      .replace(secondsReg, secondsStr);
  }
  if (onlySeconds) {
    // only seconds value is valid
    return formatWithoutHoursAndMinutes.replace(secondsReg, secondsStr);
  }
  if (hours === 0) {
    // minutes and seconds value is valid
    return formatWithoutHours
      .replace(minutesReg, minutesStr)
      .replace(secondsReg, secondsStr);
  }
  // hours、minutes and seconds value is valid
  return lowerFormat
    .replace(hoursReg, hoursStr)
    .replace(minutesReg, minutesStr)
    .replace(secondsReg, secondsStr);
}

const addZeroBeforeNum = (num) => num > 9 ? `${num}` : `0${num}`;

export default durationFormat;