Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add decimal place support #125

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 21 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var y = d * 365.25;
* Options:
*
* - `long` verbose formatting [false]
* - `decimal` decimal place [0], maximum 3 decimal place
*
* @param {String|Number} val
* @param {Object} [options]
Expand All @@ -25,11 +26,12 @@ var y = d * 365.25;

module.exports = function(val, options) {
options = options || {};
var decimal = options.decimal ? Math.min(options.decimal, 3) : 0;
var type = typeof val;
if (type === 'string' && val.length > 0) {
return parse(val);
} else if (type === 'number' && isFinite(val)) {
return options.long ? fmtLong(val) : fmtShort(val);
return options.long ? fmtLong(val, decimal) : fmtShort(val, decimal);
}
throw new Error(
'val is not a non-empty string or a valid number. val=' +
Expand Down Expand Up @@ -106,23 +108,25 @@ function parse(str) {
* Short format for `ms`.
*
* @param {Number} ms
* @param {Number} demical
* @return {String}
* @api private
*/

function fmtShort(ms) {
function fmtShort(ms, decimal) {
var msAbs = Math.abs(ms);
var base = Math.pow(10, decimal);
if (msAbs >= d) {
return Math.round(ms / d) + 'd';
return Math.round((ms / d) * base) / base + 'd';
}
if (msAbs >= h) {
return Math.round(ms / h) + 'h';
return Math.round((ms / h) * base) / base + 'h';
}
if (msAbs >= m) {
return Math.round(ms / m) + 'm';
return Math.round((ms / m) * base) / base + 'm';
}
if (msAbs >= s) {
return Math.round(ms / s) + 's';
return Math.round((ms / s) * base) / base + 's';
}
return ms + 'ms';
}
Expand All @@ -131,23 +135,24 @@ function fmtShort(ms) {
* Long format for `ms`.
*
* @param {Number} ms
* @param {Number} demical
* @return {String}
* @api private
*/

function fmtLong(ms) {
function fmtLong(ms, demical) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be decimal, right?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uhm yeah

var msAbs = Math.abs(ms);
if (msAbs >= d) {
return plural(ms, msAbs, d, 'day');
return plural(ms, msAbs, d, 'day', demical);
}
if (msAbs >= h) {
return plural(ms, msAbs, h, 'hour');
return plural(ms, msAbs, h, 'hour', demical);
}
if (msAbs >= m) {
return plural(ms, msAbs, m, 'minute');
return plural(ms, msAbs, m, 'minute', demical);
}
if (msAbs >= s) {
return plural(ms, msAbs, s, 'second');
return plural(ms, msAbs, s, 'second', demical);
}
return ms + ' ms';
}
Expand All @@ -156,7 +161,10 @@ function fmtLong(ms) {
* Pluralization helper.
*/

function plural(ms, msAbs, n, name) {
function plural(ms, msAbs, n, name, demical) {
var isPlural = msAbs >= n * 1.5;
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
var base = Math.pow(10, demical);
return (
Math.round((ms / n) * base) / base + ' ' + name + (isPlural ? 's' : '')
);
}
10 changes: 10 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ ms(-3 * 60000, { long: true }) // "-3 minutes"
ms(ms('10 hours'), { long: true }) // "10 hours"
```

### Round to decimal place

```js
ms(60000, { decimal: 1 }) // "1m"
ms(66000, { decimal: 1 }) // "1.1m"
ms(-3 * 66000, { long: true, decimal: 1 }) // "-3.3 minutes"
ms(234234234, { decimal: 2 }) // "2.71m"
ms(ms('10.5 hours'), { long: true, decimal: 1 }) // "10.5 hours"
```

## Features

- Works both in [Node.js](https://nodejs.org) and in the browser
Expand Down
167 changes: 167 additions & 0 deletions tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,173 @@ describe('ms(number)', function() {
});
});

// numbers with decimal

describe('ms(number, { long: true, decimal: n })', function() {
it('should not throw an error', function() {
expect(function() {
ms(500, { long: true, decimal: 1 });
}).to.not.throwError();
});

it('should support milliseconds', function() {
expect(ms(500, { long: true, decimal: 1 })).to.be('500 ms');

expect(ms(-500, { long: true, decimal: 1 })).to.be('-500 ms');
});

it('should support seconds', function() {
expect(ms(1000, { long: true, decimal: 1 })).to.be('1 second');
expect(ms(1200, { long: true, decimal: 1 })).to.be('1.2 second');
expect(ms(1234, { long: true, decimal: 2 })).to.be('1.23 second');
expect(ms(10000, { long: true, decimal: 1 })).to.be('10 seconds');

expect(ms(-1000, { long: true, decimal: 1 })).to.be('-1 second');
expect(ms(-1200, { long: true, decimal: 1 })).to.be('-1.2 second');
expect(ms(-10000, { long: true, decimal: 1 })).to.be('-10 seconds');
});

it('should support minutes', function() {
expect(ms(60 * 1000, { long: true, decimal: 1 })).to.be('1 minute');
expect(ms(60 * 1200, { long: true, decimal: 1 })).to.be('1.2 minute');
expect(ms(60 * 10000, { long: true, decimal: 1 })).to.be('10 minutes');

expect(ms(-1 * 60 * 1000, { long: true, decimal: 1 })).to.be('-1 minute');
expect(ms(-1 * 60 * 1200, { long: true, decimal: 1 })).to.be('-1.2 minute');
expect(ms(-1 * 60 * 10000, { long: true, decimal: 1 })).to.be(
'-10 minutes'
);
});

it('should support hours', function() {
expect(ms(60 * 60 * 1000, { long: true, decimal: 1 })).to.be('1 hour');
expect(ms(60 * 60 * 1200, { long: true, decimal: 1 })).to.be('1.2 hour');
expect(ms(60 * 60 * 10000, { long: true, decimal: 1 })).to.be('10 hours');

expect(ms(-1 * 60 * 60 * 1000, { long: true, decimal: 1 })).to.be(
'-1 hour'
);
expect(ms(-1 * 60 * 60 * 1200, { long: true, decimal: 1 })).to.be(
'-1.2 hour'
);
expect(ms(-1 * 60 * 60 * 10000, { long: true, decimal: 1 })).to.be(
'-10 hours'
);
});

it('should support days', function() {
expect(ms(24 * 60 * 60 * 1000, { long: true, decimal: 1 })).to.be('1 day');
expect(ms(24 * 60 * 60 * 1200, { long: true, decimal: 1 })).to.be(
'1.2 day'
);
expect(ms(24 * 60 * 60 * 10000, { long: true, decimal: 1 })).to.be(
'10 days'
);

expect(ms(-1 * 24 * 60 * 60 * 1000, { long: true, decimal: 1 })).to.be(
'-1 day'
);
expect(ms(-1 * 24 * 60 * 60 * 1200, { long: true, decimal: 1 })).to.be(
'-1.2 day'
);
expect(ms(-1 * 24 * 60 * 60 * 10000, { long: true, decimal: 1 })).to.be(
'-10 days'
);
});

it('should round with 2 decimal place', function() {
expect(ms(234234234, { long: true, decimal: 2 })).to.be('2.71 days');

expect(ms(-234234234, { long: true, decimal: 2 })).to.be('-2.71 days');
});

it('should round with up to 3 decimal place', function() {
expect(ms(234234234, { long: true, decimal: 3 })).to.be('2.711 days');
expect(ms(234234234, { long: true, decimal: 10 })).to.be('2.711 days');

expect(ms(-234234234, { long: true, decimal: 3 })).to.be('-2.711 days');
expect(ms(-234234234, { long: true, decimal: 10 })).to.be('-2.711 days');

expect(ms(ms('10.54321 hours'), { long: true, decimal: 1 })).to.be(
'10.5 hours'
);
expect(ms(-3 * 66121, { long: true, decimal: 1 })).to.be('-3.3 minutes');
});
});

// numbers

describe('ms(number, { decimal: n })', function() {
it('should not throw an error', function() {
expect(function() {
ms(500, { decimal: 1 });
}).to.not.throwError();
});

it('should support milliseconds', function() {
expect(ms(500, { decimal: 1 })).to.be('500ms');

expect(ms(-500, { decimal: 1 })).to.be('-500ms');
});

it('should support seconds', function() {
expect(ms(1000, { decimal: 1 })).to.be('1s');
expect(ms(1200, { decimal: 1 })).to.be('1.2s');
expect(ms(10000, { decimal: 1 })).to.be('10s');

expect(ms(-1000, { decimal: 1 })).to.be('-1s');
expect(ms(-1200, { decimal: 1 })).to.be('-1.2s');
expect(ms(-10000, { decimal: 1 })).to.be('-10s');
});

it('should support minutes', function() {
expect(ms(60 * 1000, { decimal: 1 })).to.be('1m');
expect(ms(60 * 1200, { decimal: 1 })).to.be('1.2m');
expect(ms(60 * 10000, { decimal: 1 })).to.be('10m');

expect(ms(-1 * 60 * 1000, { decimal: 1 })).to.be('-1m');
expect(ms(-1 * 60 * 1200, { decimal: 1 })).to.be('-1.2m');
expect(ms(-1 * 60 * 10000, { decimal: 1 })).to.be('-10m');
});

it('should support hours', function() {
expect(ms(60 * 60 * 1000, { decimal: 1 })).to.be('1h');
expect(ms(60 * 60 * 1200, { decimal: 1 })).to.be('1.2h');
expect(ms(60 * 60 * 10000, { decimal: 1 })).to.be('10h');

expect(ms(-1 * 60 * 60 * 1000, { decimal: 1 })).to.be('-1h');
expect(ms(-1 * 60 * 60 * 1200, { decimal: 1 })).to.be('-1.2h');
expect(ms(-1 * 60 * 60 * 10000, { decimal: 1 })).to.be('-10h');
});

it('should support days', function() {
expect(ms(24 * 60 * 60 * 1000, { decimal: 1 })).to.be('1d');
expect(ms(24 * 60 * 60 * 1200, { decimal: 1 })).to.be('1.2d');
expect(ms(24 * 60 * 60 * 10000, { decimal: 1 })).to.be('10d');

expect(ms(-1 * 24 * 60 * 60 * 1000, { decimal: 1 })).to.be('-1d');
expect(ms(-1 * 24 * 60 * 60 * 1200, { decimal: 1 })).to.be('-1.2d');
expect(ms(-1 * 24 * 60 * 60 * 10000, { decimal: 1 })).to.be('-10d');
});

it('should round with 2 decimal place', function() {
expect(ms(234234234, { decimal: 2 })).to.be('2.71d');

expect(ms(-234234234, { decimal: 2 })).to.be('-2.71d');
});

it('should round with up to 3 decimal place', function() {
expect(ms(234234234, { decimal: 3 })).to.be('2.711d');
expect(ms(234234234, { decimal: 10 })).to.be('2.711d');

expect(ms(-234234234, { decimal: 3 })).to.be('-2.711d');
expect(ms(-234234234, { decimal: 10 })).to.be('-2.711d');

expect(ms(ms('10.54321 hours'), { decimal: 1 })).to.be('10.5h');
expect(ms(-3 * 66121, { decimal: 1 })).to.be('-3.3m');
});
});

// invalid inputs

describe('ms(invalid inputs)', function() {
Expand Down