mirror of
https://github.com/kemko/nomad.git
synced 2026-01-08 19:35:41 +03:00
Duration formatting utility
The cloest Moment.js has is "homanize" which isn't precise enough.
This commit is contained in:
8
ui/app/helpers/format-duration.js
Normal file
8
ui/app/helpers/format-duration.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import Helper from '@ember/component/helper';
|
||||
import formatDuration from '../utils/format-duration';
|
||||
|
||||
function formatDurationHelper([duration], { units }) {
|
||||
return formatDuration(duration, units);
|
||||
}
|
||||
|
||||
export default Helper.helper(formatDurationHelper);
|
||||
47
ui/app/utils/format-duration.js
Normal file
47
ui/app/utils/format-duration.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import moment from 'moment';
|
||||
|
||||
const allUnits = [
|
||||
{ name: 'years', suffix: 'year', inMoment: true, pluralizable: true },
|
||||
{ name: 'months', suffix: 'month', inMoment: true, pluralizable: true },
|
||||
{ name: 'days', suffix: 'day', inMoment: true, pluralizable: true },
|
||||
{ name: 'hours', suffix: 'h', inMoment: true, pluralizable: false },
|
||||
{ name: 'minutes', suffix: 'm', inMoment: true, pluralizable: false },
|
||||
{ name: 'seconds', suffix: 's', inMoment: true, pluralizable: false },
|
||||
{ name: 'milliseconds', suffix: 'ms', inMoment: true, pluralizable: false },
|
||||
{ name: 'microseconds', suffix: 'µs', inMoment: false, pluralizable: false },
|
||||
{ name: 'nanoseconds', suffix: 'ns', inMoment: false, pluralizable: false },
|
||||
];
|
||||
|
||||
export default function formatDuration(duration = 0, units = 'ns') {
|
||||
const durationParts = {};
|
||||
|
||||
if (units === 'ns') {
|
||||
durationParts.nanoseconds = duration % 1000;
|
||||
durationParts.microseconds = Math.floor((duration % 1000000) / 1000);
|
||||
duration = Math.floor(duration / 1000000);
|
||||
} else if (units === 'mms') {
|
||||
durationParts.microseconds = duration % 1000;
|
||||
duration = Math.floor(duration / 1000);
|
||||
}
|
||||
|
||||
const momentDuration = moment.duration(duration, ['ns', 'mms'].includes(units) ? 'ms' : units);
|
||||
|
||||
allUnits
|
||||
.filterBy('inMoment')
|
||||
.mapBy('name')
|
||||
.forEach(unit => {
|
||||
durationParts[unit] = momentDuration[unit]();
|
||||
});
|
||||
|
||||
const displayParts = allUnits.reduce((parts, unitType) => {
|
||||
if (durationParts[unitType.name]) {
|
||||
const count = durationParts[unitType.name];
|
||||
const suffix =
|
||||
count === 1 || !unitType.pluralizable ? unitType.suffix : unitType.suffix.pluralize();
|
||||
parts.push(`${count}${unitType.pluralizable ? ' ' : ''}${suffix}`);
|
||||
}
|
||||
return parts;
|
||||
}, []);
|
||||
|
||||
return displayParts.join(' ');
|
||||
}
|
||||
23
ui/tests/unit/utils/format-duration-test.js
Normal file
23
ui/tests/unit/utils/format-duration-test.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { module, test } from 'ember-qunit';
|
||||
import formatDuration from 'nomad-ui/utils/format-duration';
|
||||
|
||||
module('Unit | Util | formatDuration');
|
||||
|
||||
test('When all units have values, all units are displayed', function(assert) {
|
||||
const expectation = '39 years 1 month 13 days 23h 31m 30s 987ms 654µs 400ns';
|
||||
assert.equal(formatDuration(1234567890987654321), expectation, expectation);
|
||||
});
|
||||
|
||||
test('Any unit without values gets dropped from the display', function(assert) {
|
||||
const expectation = '14 days 6h 56m 890ms 980µs';
|
||||
assert.equal(formatDuration(1234560890980000), expectation, expectation);
|
||||
});
|
||||
|
||||
test('The units option allows for units coarser than nanoseconds', function(assert) {
|
||||
const expectation1 = '1s 200ms';
|
||||
const expectation2 = '20m';
|
||||
const expectation3 = '1 month 1 day';
|
||||
assert.equal(formatDuration(1200, 'ms'), expectation1, expectation1);
|
||||
assert.equal(formatDuration(1200, 's'), expectation2, expectation2);
|
||||
assert.equal(formatDuration(32, 'd'), expectation3, expectation3);
|
||||
});
|
||||
Reference in New Issue
Block a user