Skip to content

Commit

Permalink
Add hideYears, hideYearsAndDays, and hideSeconds options (#72)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
gerbermichi and sindresorhus authored Nov 15, 2024
1 parent d00183f commit 25509bc
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 57 deletions.
21 changes: 21 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,27 @@ export type Options = {
@default false
*/
readonly colonNotation?: boolean;

/**
Hides the year and shows the hidden year additionally as days (365 per year): `1y 3d 5h 1m 45s` → `368d 5h 1m 45s`.
@default false
*/
readonly hideYear?: boolean;

/**
Hides the year and days and shows the hidden values additionally as hours: `1y 3d 5h 1m 45s` → `8837h 1m 45s`.
@default false
*/
readonly hideYearAndDays?: boolean;

/**
Hides the seconds: `1y 3d 5h 1m 45s` → `1y 3d 5h 1m`.
@default false
*/
readonly hideSeconds?: boolean;
};

/**
Expand Down
126 changes: 69 additions & 57 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,67 +61,79 @@ export default function prettyMilliseconds(milliseconds, options) {
const parsed = parseMilliseconds(milliseconds);
const days = BigInt(parsed.days);

add(days / 365n, 'year', 'y');
add(days % 365n, 'day', 'd');
add(Number(parsed.hours), 'hour', 'h');
if (options.hideYearAndDays) {
add((BigInt(days) * 24n) + BigInt(parsed.hours), 'hour', 'h');
} else {
if (options.hideYear) {
add(days, 'day', 'd');
} else {
add(days / 365n, 'year', 'y');
add(days % 365n, 'day', 'd');
}

add(Number(parsed.hours), 'hour', 'h');
}

add(Number(parsed.minutes), 'minute', 'm');

if (
options.separateMilliseconds
|| options.formatSubMilliseconds
|| (!options.colonNotation && milliseconds < 1000)
) {
const seconds = Number(parsed.seconds);
const milliseconds = Number(parsed.milliseconds);
const microseconds = Number(parsed.microseconds);
const nanoseconds = Number(parsed.nanoseconds);

add(seconds, 'second', 's');

if (options.formatSubMilliseconds) {
add(milliseconds, 'millisecond', 'ms');
add(microseconds, 'microsecond', 'µs');
add(nanoseconds, 'nanosecond', 'ns');
if (!options.hideSeconds) {
if (
options.separateMilliseconds
|| options.formatSubMilliseconds
|| (!options.colonNotation && milliseconds < 1000)
) {
const seconds = Number(parsed.seconds);
const milliseconds = Number(parsed.milliseconds);
const microseconds = Number(parsed.microseconds);
const nanoseconds = Number(parsed.nanoseconds);

add(seconds, 'second', 's');

if (options.formatSubMilliseconds) {
add(milliseconds, 'millisecond', 'ms');
add(microseconds, 'microsecond', 'µs');
add(nanoseconds, 'nanosecond', 'ns');
} else {
const millisecondsAndBelow
= milliseconds
+ (microseconds / 1000)
+ (nanoseconds / 1e6);

const millisecondsDecimalDigits
= typeof options.millisecondsDecimalDigits === 'number'
? options.millisecondsDecimalDigits
: 0;

const roundedMilliseconds = millisecondsAndBelow >= 1
? Math.round(millisecondsAndBelow)
: Math.ceil(millisecondsAndBelow);

const millisecondsString = millisecondsDecimalDigits
? millisecondsAndBelow.toFixed(millisecondsDecimalDigits)
: roundedMilliseconds;

add(
Number.parseFloat(millisecondsString),
'millisecond',
'ms',
millisecondsString,
);
}
} else {
const millisecondsAndBelow
= milliseconds
+ (microseconds / 1000)
+ (nanoseconds / 1e6);

const millisecondsDecimalDigits
= typeof options.millisecondsDecimalDigits === 'number'
? options.millisecondsDecimalDigits
: 0;

const roundedMilliseconds = millisecondsAndBelow >= 1
? Math.round(millisecondsAndBelow)
: Math.ceil(millisecondsAndBelow);

const millisecondsString = millisecondsDecimalDigits
? millisecondsAndBelow.toFixed(millisecondsDecimalDigits)
: roundedMilliseconds;

add(
Number.parseFloat(millisecondsString),
'millisecond',
'ms',
millisecondsString,
);
const seconds = (
(isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds)
/ 1000
) % 60;
const secondsDecimalDigits
= typeof options.secondsDecimalDigits === 'number'
? options.secondsDecimalDigits
: 1;
const secondsFixed = floorDecimals(seconds, secondsDecimalDigits);
const secondsString = options.keepDecimalsOnWholeSeconds
? secondsFixed
: secondsFixed.replace(/\.0+$/, '');
add(Number.parseFloat(secondsString), 'second', 's', secondsString);
}
} else {
const seconds = (
(isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds)
/ 1000
) % 60;
const secondsDecimalDigits
= typeof options.secondsDecimalDigits === 'number'
? options.secondsDecimalDigits
: 1;
const secondsFixed = floorDecimals(seconds, secondsDecimalDigits);
const secondsString = options.keepDecimalsOnWholeSeconds
? secondsFixed
: secondsFixed.replace(/\.0+$/, '');
add(Number.parseFloat(secondsString), 'second', 's', secondsString);
}

if (result.length === 0) {
Expand Down
21 changes: 21 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,27 @@ Setting `colonNotation` to `true` overrides the following options to `false`:
- `separateMilliseconds`
- `verbose`

##### hideYear

Type: `boolean`\
Default: `false`

Hides the year and shows the hidden year additionally as days (365 per year): `1y 3d 5h 1m 45s``368d 5h 1m 45s`.

##### hideYearAndDays

Type: `boolean`\
Default: `false`

Hides the year and days and shows the hidden values additionally as hours: `1y 3d 5h 1m 45s``8837h 1m 45s`.

##### hideSeconds

Type: `boolean`\
Default: `false`

Hides the seconds: `1y 3d 5h 1m 45s``1y 3d 5h 1m`.

## Related

- [pretty-ms-cli](https://github.com/sindresorhus/pretty-ms-cli) - CLI for this module
Expand Down
61 changes: 61 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,67 @@ runTests({
],
});

runTests({
title: 'have a hideYear option',
cases: [
[1000 * 60, {hideYear: true}, '1m'],
[1000 * 60, {hideYear: false}, '1m'],
[1000 * 60 * 67, {hideYear: true}, '1h 7m'],
[1000 * 60 * 67, {hideYear: false}, '1h 7m'],
[1000 * 60 * 67 * 24 * 465, {hideYear: false}, '1y 154d 6h'],
[1000 * 60 * 67 * 24 * 465, {hideYear: true}, '519d 6h'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYear: false}, '1y 154d 6h 1m 6.5s'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYear: true}, '519d 6h 1m 6.5s'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYear: true, secondsDecimalDigits: 0}, '519d 6h 1m 6s'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6000, {hideYear: true, keepDecimalsOnWholeSeconds: true}, '519d 6h 1m 6.0s'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYear: true, separateMilliseconds: true}, '519d 6h 1m 6s 500ms'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYear: true, verbose: true}, '519 days 6 hours 1 minute 6.5 seconds'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYear: true, compact: true}, '519d'],
],
});

runTests({
title: 'have a hideYearAndDays option',
cases: [
[1000 * 60, {hideYearAndDays: true}, '1m'],
[1000 * 60, {hideYearAndDays: false}, '1m'],
[1000 * 60 * 67, {hideYearAndDays: false}, '1h 7m'],
[1000 * 60 * 67, {hideYearAndDays: true}, '1h 7m'],
[1000 * 60 * 67 * 24 * 465, {hideYearAndDays: false}, '1y 154d 6h'],
[1000 * 60 * 67 * 24 * 465, {hideYearAndDays: true}, '12462h'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYearAndDays: false}, '1y 154d 6h 1m 6.5s'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYearAndDays: true}, '12462h 1m 6.5s'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYearAndDays: true, secondsDecimalDigits: 0}, '12462h 1m 6s'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6000, {hideYearAndDays: true, keepDecimalsOnWholeSeconds: true}, '12462h 1m 6.0s'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYearAndDays: true, separateMilliseconds: true}, '12462h 1m 6s 500ms'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYearAndDays: true, verbose: true}, '12462 hours 1 minute 6.5 seconds'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60) + 6500, {hideYearAndDays: true, compact: true}, '12462h'],
],
});

runTests({
title: 'have a hideSeconds option',
cases: [
[(1000 * 60) + 6500, {hideSeconds: false}, '1m 6.5s'],
[(1000 * 60) + 6500, {hideSeconds: true}, '1m'],
[(1000 * 60) + 6500, {hideSeconds: true, secondsDecimalDigits: 3}, '1m'],
[(1000 * 60) + 6500, {hideSeconds: true, keepDecimalsOnWholeSeconds: true}, '1m'],
[(1000 * 60) + 6500, {hideSeconds: true, formatSubMilliseconds: true}, '1m'],
[(1000 * 60) + 6500, {hideSeconds: true, separateMilliseconds: true}, '1m'],
[(1000 * 60) + 6500, {hideSeconds: true, verbose: true}, '1 minute'],
[(1000 * 60) + 6500, {hideSeconds: true, compact: true}, '1m'],
],
});

runTests({
title: 'have hideYearAndDays,hideSeconds and colonNotation options',
cases: [
[(1000 * 60 * 60 * 15) + (1000 * 60 * 59) + (1000 * 59) + 543, {hideSeconds: true, hideYearAndDays: true, colonNotation: true}, '15:59'],
[(1000 * 60 * 67 * 24 * 465) + (1000 * 60 * 60 * 15) + (1000 * 60 * 59) + (1000 * 59) + 543, {hideSeconds: true, hideYearAndDays: true, colonNotation: true}, '12477:59'],
[BigInt(Number.MAX_VALUE), {hideSeconds: true, hideYearAndDays: true, colonNotation: true}, '49935920412842103004035395481028987999464046534956943499699299111988127994452371877941544064657466158761238598198439573398422590802628939657907651862093754718347197382375356132290413913997035817798852363459759428417939788028673041157169044258923152298554951723373534213538382550255361078125112229495590:14'],
],
});

test('Big numbers', t => {
t.is(
prettyMilliseconds(Number.MAX_VALUE),
Expand Down

0 comments on commit 25509bc

Please sign in to comment.