Skip to content

Commit

Permalink
Add option to format microseconds and nanoseconds (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mees van Dijk authored and sindresorhus committed Sep 17, 2018
1 parent 7602f88 commit 0950e70
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 11 deletions.
36 changes: 27 additions & 9 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ module.exports = (ms, options = {}) => {
throw new TypeError('Expected a finite number');
}

if (ms < 1000) {
const msDecimalDigits = typeof options.msDecimalDigits === 'number' ? options.msDecimalDigits : 0;
return (msDecimalDigits ? ms.toFixed(msDecimalDigits) : Math.ceil(ms)) + (options.verbose ? ' ' + pluralize('millisecond', Math.ceil(ms)) : 'ms');
if (options.compact) {
options.secDecimalDigits = 0;
options.msDecimalDigits = 0;
}

const ret = [];
Expand Down Expand Up @@ -41,15 +41,33 @@ module.exports = (ms, options = {}) => {
add(parsed.hours, 'hour', 'h');
add(parsed.minutes, 'minute', 'm');

if (options.compact) {
if (options.separateMs || options.formatSubMs || ms < 1000) {
add(parsed.seconds, 'second', 's');
return '~' + ret[0];
if (options.formatSubMs) {
add(parsed.milliseconds, 'millisecond', 'ms');
add(parsed.microseconds, 'microsecond', 'µs');
add(parsed.nanoseconds, 'nanosecond', 'ns');
} else {
const msAndBelow = parsed.milliseconds + (parsed.microseconds / 1000) + (parsed.nanoseconds / 1e6);
const msDecimalDigits = typeof options.msDecimalDigits === 'number' ? options.msDecimalDigits : 0;
const msStr = msDecimalDigits ? msAndBelow.toFixed(msDecimalDigits) : Math.ceil(msAndBelow);
add(parseFloat(msStr, 10), 'millisecond', 'ms', msStr);
}
} else {
const sec = ms / 1000 % 60;
const secDecimalDigits = typeof options.secDecimalDigits === 'number' ? options.secDecimalDigits : 1;
const secFixed = sec.toFixed(secDecimalDigits);
const secStr = options.keepDecimalsOnWholeSeconds ? secFixed : secFixed.replace(/\.0+$/, '');
add(parseFloat(secStr, 10), 'second', 's', secStr);
}

const sec = ms / 1000 % 60;
const secFixed = sec.toFixed(secDecimalDigits);
const secStr = options.keepDecimalsOnWholeSeconds ? secFixed : secFixed.replace(/\.0+$/, '');
add(sec, 'second', 's', secStr);
if (ret.length === 0) {
return '0' + (options.verbose ? ' milliseconds' : 'ms');
}

if (options.compact) {
return '~' + ret[0];
}

return ret.join(' ');
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"hrtime"
],
"dependencies": {
"parse-ms": "^1.0.1"
"parse-ms": "^2.0.0"
},
"devDependencies": {
"ava": "*",
Expand Down
21 changes: 20 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ prettyMs(1337, {compact: true});
prettyMs(1335669000, {verbose: true});
//=> '15 days 11 hours 1 minute 9 seconds'

// formatSubMs option
prettyMs(100.400080, {formatSubMs: true})
//=> '100ms 400µs 80ns'

// can be useful for time durations
prettyMs(new Date(2014, 0, 1, 10, 40) - new Date(2014, 0, 1, 10, 5))
//=> '35m'
Expand Down Expand Up @@ -82,7 +86,8 @@ Useful when you are showing a number of seconds spent on an operation and don't
Type: `boolean`<br>
Default: `false`

Only show the first unit: `1h 10m``~1h`.
Only show the first unit: `1h 10m``~1h`.
Also ensures that `msDecimalDigits` and `secDecimalDigits` are both set to `0`.

##### verbose

Expand All @@ -91,6 +96,20 @@ Default: `false`

Use full-length units: `5h 1m 45s``5 hours 1 minute 45 seconds`

#### separateMs

Type: `boolean`<br>
Default: `false`

Show milliseconds separately. This means they won't be included in the decimal part of the seconds.

#### formatSubMs

Type: `boolean`<br>
Default: `false`

Show microseconds and nanoseconds.


## Related

Expand Down
24 changes: 24 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ test('have a verbose option', t => {
t.is(fn(1000 * 60 * 67 * 24 * 465), '1 year 154 days 6 hours');
});

test('have a separateMs option', t => {
t.is(m(1100, {separateMs: false}), '1.1s');
t.is(m(1100, {separateMs: true}), '1s 100ms');
});

test('have a formatSubMs option', t => {
t.is(m(0.400, {formatSubMs: true}), '400µs');
t.is(m(0.123571, {formatSubMs: true}), '123µs 571ns');
t.is(m(0.123456789, {formatSubMs: true}), '123µs 456ns');
t.is(m((60 * 60 * 1000) + (23 * 1000) + 433 + 0.123456, {formatSubMs: true}), '1h 23s 433ms 123µs 456ns');
});

test('work with verbose and compact options', t => {
const fn = ms => m(ms, {
verbose: true,
Expand Down Expand Up @@ -111,6 +123,18 @@ test('work with verbose and msDecimalDigits options', t => {
t.is(fn(33.333), '33.3330 milliseconds');
});

test('work with verbose and formatSubMs options', t => {
t.is(m(0.400, {formatSubMs: true, verbose: true}), '400 microseconds');
t.is(m(0.123571, {formatSubMs: true, verbose: true}), '123 microseconds 571 nanoseconds');
t.is(m(0.123456789, {formatSubMs: true, verbose: true}), '123 microseconds 456 nanoseconds');
t.is(m(0.001, {formatSubMs: true, verbose: true}), '1 microsecond');
});

test('work with separateMs and formatSubMs options', t => {
t.is(m(1010.340067, {separateMs: true, formatSubMs: true}), '1s 10ms 340µs 67ns');
t.is(m(((60 * 1000) + 34 + 0.000005), {separateMs: true, formatSubMs: true}), '1m 34ms 5ns');
});

test('throw on invalid', t => {
t.throws(() => {
m('foo');
Expand Down

0 comments on commit 0950e70

Please sign in to comment.