Skip to content

Commit bfba184

Browse files
committed
feat: add function to stringify numbers to time strings
1 parent 044f961 commit bfba184

File tree

5 files changed

+118
-32
lines changed

5 files changed

+118
-32
lines changed

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<h1 align="center">@compactjs/parse-time</h1>
2-
<h3 align="center">Tiny time parser</h3>
2+
<h3 align="center">Tiny hour parser & stringifier</h3>
33
<p align="center">
44
<a href="https://www.npmjs.com/package/@compactjs/parse-time" target="_blank">
55
<img alt="Version" src="https://img.shields.io/npm/v/@compactjs/parse-time.svg">
@@ -44,13 +44,30 @@ npm install @compactjs/parse-time
4444
### As module:
4545

4646
```javascript
47-
import { parse } from '@compactjs/parse-time';
47+
import { parse, stringify } from '@compactjs/parse-time';
4848
```
4949

5050
### Example:
5151

5252
```javascript
53+
// parse a time string to a number
5354
parse('13:30'); // => 13.5
55+
parse('13:19:48'); // => 13.33
56+
57+
// stringify a number to a time string
58+
stringify(13.33); // => 13:19:48
59+
60+
// formating options:
61+
stringify(13.33, 'hh'); // => 13
62+
stringify(13.33, 'hh:mm'); // => 13:19
63+
stringify(13.33, 'hh:mm:ss'); // => 13:19:48
64+
65+
// it accepts numbers higher than 24
66+
stringify(34.5); // => 34:30:00
67+
68+
// to limit to a range between 0 and 24 (or 0-12),
69+
// I recommend to use https://github.com/CompactJS/limit
70+
stringify(limit(34.5, 24)); // => 10:30:00
5471
```
5572

5673
## Run tests

src/index.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,32 @@ export function parse(timeString: string): number {
99
.split(':')
1010
.reduce((hours, hour, i) => hours + parseInt(hour) / Math.pow(60, i), 0);
1111
}
12+
13+
type TimeUnit = 'hh' | 'mm' | 'ss';
14+
type TimeFormat =
15+
| `${TimeUnit}`
16+
| `${TimeUnit}:${TimeUnit}`
17+
| `${TimeUnit}:${TimeUnit}:${TimeUnit}`;
18+
19+
/**
20+
* Converts hours as float to a string representation, separated by colon
21+
* @param hours time as float
22+
* @returns Time as string Format: 'hh:mm[:ss]'
23+
* @example stringify(11.5) // => '11:30'
24+
*/
25+
export function stringify(
26+
hours: number,
27+
format: TimeFormat = 'hh:mm:ss'
28+
): string {
29+
const hoursString = pad(Math.floor(hours));
30+
const minutesString = pad(Math.floor(hours * 60) % 60);
31+
const secondsString = pad(Math.floor(hours * 3600) % 60);
32+
return format
33+
.replace(/hh/g, hoursString)
34+
.replace(/mm/g, minutesString)
35+
.replace(/ss/g, secondsString);
36+
}
37+
38+
function pad(number: string | number): string {
39+
return `${number}`.length === 1 ? `0${number}` : `${number}`;
40+
}

test/index.test.js

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,5 @@
1-
const assert = require('assert');
2-
const { parse } = require('..');
1+
const testParseFunction = require('./parse.test');
2+
const testStringifyFunction = require('./stringify.test');
33

4-
console.log('Testing:');
5-
6-
const test = (example) => {
7-
const log = (example, expected) =>
8-
console.log(`\u001B[32m✓\u001B[39m ${example} = ${expected}`);
9-
return {
10-
isNaN() {
11-
assert(isNaN(example));
12-
log(example, 'NaN');
13-
},
14-
equals(expected) {
15-
assert.equal(parse(example), expected);
16-
log(example, expected);
17-
},
18-
};
19-
};
20-
21-
test('00:00').equals(0);
22-
test('12:30').equals(12.5);
23-
test('24:00').equals(24);
24-
test('02:14').equals(2 + 14 / 60);
25-
test('60:366').equals(66.1);
26-
test('13:30:30').equals(13 + 0.5 + 0.5 / 60);
27-
test('1:1').equals(1 + 1 / 60);
28-
test('hello:world').isNaN();
29-
test('helloworld').isNaN();
30-
test(':30').isNaN();
31-
test('60:60:60:60').equals(61 + 60 / 60 / 60 + 60 / 60 / 60 / 60);
4+
testParseFunction();
5+
testStringifyFunction();

test/parse.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const assert = require('assert');
2+
const { parse } = require('..');
3+
4+
const test = (example) => {
5+
const log = (example, expected) =>
6+
console.log(`\u001B[32m✓\u001B[39m ${example} = ${expected}`);
7+
return {
8+
isNaN() {
9+
assert(isNaN(parse(example)));
10+
log(example, 'NaN');
11+
},
12+
equals(expected) {
13+
assert.equal(parse(example), expected);
14+
log(example, expected);
15+
},
16+
};
17+
};
18+
19+
module.exports = function () {
20+
console.log('Testing, parse function.');
21+
test('00:00').equals(0);
22+
test('12:30').equals(12.5);
23+
test('24:00').equals(24);
24+
test('02:14').equals(2 + 14 / 60);
25+
test('60:366').equals(66.1);
26+
test('13:30:30').equals(13 + 0.5 + 0.5 / 60);
27+
test('1:1').equals(1 + 1 / 60);
28+
test('hello:world').isNaN();
29+
test('helloworld').isNaN();
30+
test(':30').isNaN();
31+
test('60:60:60:60').equals(61 + 60 / 60 / 60 + 60 / 60 / 60 / 60);
32+
};

test/stringify.test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const assert = require('assert');
2+
const { stringify } = require('..');
3+
4+
const test = (example, format) => {
5+
const log = (example, expected) =>
6+
console.log(`\u001B[32m✓\u001B[39m ${example} = ${expected}`);
7+
return {
8+
isNaN() {
9+
assert(isNaN(stringify(example)));
10+
log(example, 'NaN');
11+
},
12+
equals(expected) {
13+
assert.strictEqual(stringify(example, format), expected);
14+
log(example, expected);
15+
},
16+
};
17+
};
18+
19+
module.exports = function () {
20+
console.log('Testing stringify function');
21+
test(0, 'hh:mm').equals('00:00');
22+
test(0, 'hh:mm:ss').equals('00:00:00');
23+
test(1.5, 'hh:mm:ss').equals('01:30:00');
24+
test(13.33, 'hh:mm:ss').equals('13:19:48');
25+
test(13.33, 'mm:ss').equals('19:48');
26+
// weird format, but it's a valid format
27+
test(13.33, 'ss:hh:mm').equals('48:13:19');
28+
29+
// invalid input
30+
test('23:43:39', 'hh:mm:ss').equals('NaN:NaN:NaN');
31+
32+
// more than 24 hours allowed
33+
test(34.5).equals('34:30:00');
34+
};

0 commit comments

Comments
 (0)