in app/assets/javascripts/chronic_duration.js [231:423]
export function outputChronicDuration(seconds, opts = {}) {
if (opts.hoursOnly) {
const hours = Math.round(seconds / 3600);
return `${hours}h`;
}
const units = {
years: 0,
months: 0,
weeks: 0,
days: 0,
hours: 0,
minutes: 0,
seconds,
};
const hoursPerDay = opts.hoursPerDay || HOURS_PER_DAY;
const daysPerMonth = opts.daysPerMonth || DAYS_PER_MONTH;
const daysPerWeek = Math.trunc(daysPerMonth / FULL_WEEKS_PER_MONTH);
const decimalPlaces =
seconds % 1 !== 0 ? seconds.toString().split('.').reverse()[0].length : null;
const minute = 60;
const hour = 60 * minute;
const day = hoursPerDay * hour;
const month = daysPerMonth * day;
const year = 31557600;
if (units.seconds >= 31557600 && units.seconds % year < units.seconds % month) {
units.years = Math.trunc(units.seconds / year);
units.months = Math.trunc((units.seconds % year) / month);
units.days = Math.trunc(((units.seconds % year) % month) / day);
units.hours = Math.trunc((((units.seconds % year) % month) % day) / hour);
units.minutes = Math.trunc(((((units.seconds % year) % month) % day) % hour) / minute);
units.seconds = Math.trunc(((((units.seconds % year) % month) % day) % hour) % minute);
} else if (seconds >= 60) {
units.minutes = Math.trunc(seconds / 60);
units.seconds %= 60;
if (units.minutes >= 60) {
units.hours = Math.trunc(units.minutes / 60);
units.minutes = Math.trunc(units.minutes % 60);
if (!opts.limitToHours) {
if (units.hours >= hoursPerDay) {
units.days = Math.trunc(units.hours / hoursPerDay);
units.hours = Math.trunc(units.hours % hoursPerDay);
if (opts.weeks) {
if (units.days >= daysPerWeek) {
units.weeks = Math.trunc(units.days / daysPerWeek);
units.days = Math.trunc(units.days % daysPerWeek);
if (units.weeks >= FULL_WEEKS_PER_MONTH) {
units.months = Math.trunc(units.weeks / FULL_WEEKS_PER_MONTH);
units.weeks = Math.trunc(units.weeks % FULL_WEEKS_PER_MONTH);
}
}
} else if (units.days >= daysPerMonth) {
units.months = Math.trunc(units.days / daysPerMonth);
units.days = Math.trunc(units.days % daysPerMonth);
}
}
}
}
}
let joiner = opts.joiner || ' ';
let process = null;
let dividers;
switch (opts.format) {
case 'micro':
dividers = {
years: 'y',
months: 'mo',
weeks: 'w',
days: 'd',
hours: 'h',
minutes: 'm',
seconds: 's',
};
joiner = '';
break;
case 'short':
dividers = {
years: 'y',
months: 'mo',
weeks: 'w',
days: 'd',
hours: 'h',
minutes: 'm',
seconds: 's',
};
break;
case 'long':
dividers = {
/* eslint-disable @gitlab/require-i18n-strings */
years: ' year',
months: ' month',
weeks: ' week',
days: ' day',
hours: ' hour',
minutes: ' minute',
seconds: ' second',
/* eslint-enable @gitlab/require-i18n-strings */
pluralize: true,
};
break;
case 'chrono':
dividers = {
years: ':',
months: ':',
weeks: ':',
days: ':',
hours: ':',
minutes: ':',
seconds: ':',
keepZero: true,
};
process = (str) => {
// Pad zeros
// Get rid of lead off times if they are zero
// Get rid of lead off zero
// Get rid of trailing:
const divider = ':';
const processed = [];
str.split(divider).forEach((n) => {
if (n === '') {
return;
}
// add zeros only if n is an integer
if (n.search('\\.') >= 0) {
processed.push(
parseFloat(n)
.toFixed(decimalPlaces)
.padStart(3 + decimalPlaces, '0'),
);
} else {
processed.push(n.padStart(2, '0'));
}
});
return processed
.join(divider)
.replace(/^(00:)+/g, '')
.replace(/^0/g, '')
.replace(/:$/g, '');
};
joiner = '';
break;
default:
dividers = {
/* eslint-disable @gitlab/require-i18n-strings */
years: ' yr',
months: ' mo',
weeks: ' wk',
days: ' day',
hours: ' hr',
minutes: ' min',
seconds: ' sec',
/* eslint-enable @gitlab/require-i18n-strings */
pluralize: true,
};
break;
}
let result = [];
['years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds'].forEach((t) => {
if (t === 'weeks' && !opts.weeks) {
return;
}
let num = units[t];
if (t === 'seconds' && num % 0 !== 0) {
num = num.toFixed(decimalPlaces);
} else {
num = num.toString();
}
const keepZero = !dividers.keepZero && t === 'seconds' ? opts.keepZero : dividers.keepZero;
const humanized = humanizeTimeUnit(num, dividers[t], dividers.pluralize, keepZero);
if (humanized !== null) {
result.push(humanized);
}
});
if (opts.units) {
result = result.slice(0, opts.units);
}
result = result.join(joiner);
if (process) {
result = process(result);
}
return result.length === 0 ? null : result;
}