Skip to content

Commit

Permalink
Merge branch 'main' into support-bigint
Browse files Browse the repository at this point in the history
# Conflicts:
#	index.d.ts
#	index.js
#	index.test-d.ts
#	package.json
#	test.js
  • Loading branch information
fisker committed Jan 7, 2024
2 parents ff76116 + b222100 commit e69549c
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 49 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ jobs:
fail-fast: false
matrix:
node-version:
- 14
- 12
- 20
- 18
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
4 changes: 2 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export interface TimeComponents<T extends number | bigint> {
export type TimeComponents<T extends number | bigint> = {
days: T;
hours: T;
minutes: T;
seconds: T;
milliseconds: T;
microseconds: T;
nanoseconds: T;
}
};

/**
Parse milliseconds into an object.
Expand Down
31 changes: 18 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,42 @@
const toZeroIfInfinity = value => Number.isFinite(value) ? value : 0;

function parseNumber(milliseconds) {
return {
days: Math.trunc(milliseconds / 86400000),
hours: Math.trunc(milliseconds / 3600000) % 24,
minutes: Math.trunc(milliseconds / 60000) % 60,
seconds: Math.trunc(milliseconds / 1000) % 60,
milliseconds: Math.trunc(milliseconds) % 1000,
microseconds: Math.trunc(milliseconds * 1000) % 1000,
nanoseconds: Math.trunc(milliseconds * 1e6) % 1000
days: Math.trunc(milliseconds / 86_400_000),
hours: Math.trunc(milliseconds / 3_600_000 % 24),
minutes: Math.trunc(milliseconds / 60_000 % 60),
seconds: Math.trunc(milliseconds / 1000 % 60),
milliseconds: Math.trunc(milliseconds % 1000),
microseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1000) % 1000),
nanoseconds: Math.trunc(toZeroIfInfinity(milliseconds * 1e6) % 1000),
};
}

function parseBigint(milliseconds) {
return {
days: milliseconds / 86400000n,
hours: milliseconds / 3600000n % 24n,
minutes: milliseconds / 60000n % 60n,
days: milliseconds / 86_400_000n,
hours: milliseconds / 3_600_000n % 24n,
minutes: milliseconds / 60_000n % 60n,
seconds: milliseconds / 1000n % 60n,
milliseconds: milliseconds % 1000n,
microseconds: 0n,
nanoseconds: 0n
nanoseconds: 0n,
};
}

export default function parseMilliseconds(milliseconds) {
switch (typeof milliseconds) {
case 'number':
case 'number': {
if (Number.isFinite(milliseconds)) {
return parseNumber(milliseconds);
}

break;
case 'bigint':
}

case 'bigint': {
return parseBigint(milliseconds);
}

// No default
}
Expand Down
4 changes: 2 additions & 2 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {expectType, expectError} from 'tsd';
import parseMilliseconds, {TimeComponents} from './index.js';
import {expectType} from 'tsd';
import parseMilliseconds, {type TimeComponents} from './index.js';

const result1: TimeComponents<number> = parseMilliseconds(3000);

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=12"
"node": ">=18"
},
"scripts": {
"test": "xo && ava && tsd"
Expand All @@ -36,8 +36,8 @@
"interval"
],
"devDependencies": {
"ava": "^3.15.0",
"ava": "^6.0.1",
"tsd": "^0.30.3",
"xo": "^0.38.2"
"xo": "^0.56.0"
}
}
70 changes: 45 additions & 25 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ function runTest(t, milliseconds, expected) {
t.deepEqual(
parseMilliseconds(bigint),
Object.fromEntries(
Object.entries(expected).map(([unit, value]) => [unit, BigInt(value)])
)
Object.entries(expected).map(([unit, value]) => [unit, BigInt(value)]),
),
);
}

Expand All @@ -42,7 +42,7 @@ test('parse milliseconds into an object', t => {
seconds: 1,
milliseconds: 400,
microseconds: 0,
nanoseconds: 0
nanoseconds: 0,
});

runTest(t, 1000 * 55, {
Expand All @@ -52,7 +52,7 @@ test('parse milliseconds into an object', t => {
seconds: 55,
milliseconds: 0,
microseconds: 0,
nanoseconds: 0
nanoseconds: 0,
});

runTest(t, 1000 * 67, {
Expand All @@ -62,7 +62,7 @@ test('parse milliseconds into an object', t => {
seconds: 7,
milliseconds: 0,
microseconds: 0,
nanoseconds: 0
nanoseconds: 0,
});

runTest(t, 1000 * 60 * 5, {
Expand All @@ -72,7 +72,7 @@ test('parse milliseconds into an object', t => {
seconds: 0,
milliseconds: 0,
microseconds: 0,
nanoseconds: 0
nanoseconds: 0,
});

runTest(t, 1000 * 60 * 67, {
Expand All @@ -82,7 +82,7 @@ test('parse milliseconds into an object', t => {
seconds: 0,
milliseconds: 0,
microseconds: 0,
nanoseconds: 0
nanoseconds: 0,
});

runTest(t, 1000 * 60 * 60 * 12, {
Expand All @@ -92,7 +92,7 @@ test('parse milliseconds into an object', t => {
seconds: 0,
milliseconds: 0,
microseconds: 0,
nanoseconds: 0
nanoseconds: 0,
});

runTest(t, 1000 * 60 * 60 * 40, {
Expand All @@ -102,7 +102,7 @@ test('parse milliseconds into an object', t => {
seconds: 0,
milliseconds: 0,
microseconds: 0,
nanoseconds: 0
nanoseconds: 0,
});

runTest(t, 1000 * 60 * 60 * 999, {
Expand All @@ -112,52 +112,72 @@ test('parse milliseconds into an object', t => {
seconds: 0,
milliseconds: 0,
microseconds: 0,
nanoseconds: 0
nanoseconds: 0,
});

runTest(t, (1000 * 60) + 500 + 0.345678, {
runTest(t, (1000 * 60) + 500 + 0.345_678, {
days: 0,
hours: 0,
minutes: 1,
seconds: 0,
milliseconds: 500,
microseconds: 345,
nanoseconds: 678
nanoseconds: 678,
});

runTest(t, 0.000543, {
runTest(t, 0.000_543, {
days: 0,
hours: 0,
minutes: 0,
seconds: 0,
milliseconds: 0,
microseconds: 0,
nanoseconds: 543
nanoseconds: 543,
});

runTest(
t,
0n +
0n
// 1ms
1n +
+ 1n
// 2s
(2n * 1000n) +
+ (2n * 1000n)
// 3m
(3n * 1000n * 60n) +
+ (3n * 1000n * 60n)
// 4h
(4n * 1000n * 60n * 60n) +
+ (4n * 1000n * 60n * 60n)
// Days
(BigInt(Number.MAX_VALUE) * 1000n * 60n * 60n * 24n),
+ (BigInt(Number.MAX_VALUE) * 1000n * 60n * 60n * 24n),
{
days: BigInt(Number.MAX_VALUE),
hours: 4n,
minutes: 3n,
seconds: 2n,
milliseconds: 1n,
microseconds: 0n,
nanoseconds: 0n
}
nanoseconds: 0n,
},
);

t.deepEqual(parseMilliseconds(Number.MAX_VALUE), {
days: 2.080_663_350_535_087_5e+300,
hours: 8,
minutes: 8,
seconds: 48,
milliseconds: 368,
microseconds: 0,
nanoseconds: 0,
});

t.deepEqual(parseMilliseconds(Number.MIN_VALUE), {
days: 0,
hours: 0,
minutes: 0,
seconds: 0,
milliseconds: 0,
microseconds: 0,
nanoseconds: 0,
});
});

test('handle negative millisecond values', t => {
Expand All @@ -166,7 +186,7 @@ test('handle negative millisecond values', t => {
'hours',
'minutes',
'seconds',
'milliseconds'
'milliseconds',
];

const times = [
Expand All @@ -180,9 +200,9 @@ test('handle negative millisecond values', t => {
1000 * 60 * 67,
1000 * 60 * 60 * 12,
1000 * 60 * 60 * 40,
1000 * 60 * 60 * 999
1000 * 60 * 60 * 999,
].flatMap(number => [number, toBigInt(number)]),
BigInt('0x' + 'F'.repeat(1e6))
BigInt('0x' + 'F'.repeat(1e6)),
];

for (const milliseconds of times) {
Expand Down

0 comments on commit e69549c

Please sign in to comment.