From 4e31aabe21aa4cb7eea786b570a3306dde1a542c Mon Sep 17 00:00:00 2001 From: Sky Chen Date: Sun, 20 Oct 2019 01:53:49 -0700 Subject: [PATCH 1/4] Add decimal place support --- index.js | 34 +++++++---- package.json | 3 + readme.md | 10 +++ tests.js | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 201 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index c4498bc..4832ad3 100644 --- a/index.js +++ b/index.js @@ -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] @@ -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=' + @@ -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'; } @@ -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) { 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'; } @@ -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' : '') + ); } diff --git a/package.json b/package.json index e78eb33..1fa1c90 100644 --- a/package.json +++ b/package.json @@ -33,5 +33,8 @@ "husky": "0.14.3", "lint-staged": "5.0.0", "mocha": "4.0.1" + }, + "dependencies": { + "prettier": "1.18.2" } } diff --git a/readme.md b/readme.md index 9a1996b..d0615dd 100644 --- a/readme.md +++ b/readme.md @@ -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 diff --git a/tests.js b/tests.js index 1d0d663..0ba7dfe 100644 --- a/tests.js +++ b/tests.js @@ -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() { From f2ca033bbd3043bd74294ff2a88f3000a5a5e8e6 Mon Sep 17 00:00:00 2001 From: Sky Chen Date: Sun, 20 Oct 2019 01:57:43 -0700 Subject: [PATCH 2/4] remove dependency --- package.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/package.json b/package.json index 1fa1c90..e78eb33 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,5 @@ "husky": "0.14.3", "lint-staged": "5.0.0", "mocha": "4.0.1" - }, - "dependencies": { - "prettier": "1.18.2" } } From 145e0abb9f4887882752ea665ac890e7116c24be Mon Sep 17 00:00:00 2001 From: Sky Chen Date: Sun, 20 Oct 2019 02:02:19 -0700 Subject: [PATCH 3/4] update readme --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index d0615dd..5b2defa 100644 --- a/readme.md +++ b/readme.md @@ -43,8 +43,8 @@ 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(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" From 9e238ddfa922fcde52c4989da5e6d1a1a0f6c475 Mon Sep 17 00:00:00 2001 From: Sky Chen Date: Sun, 20 Oct 2019 02:04:06 -0700 Subject: [PATCH 4/4] update readme --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 5b2defa..700f9f8 100644 --- a/readme.md +++ b/readme.md @@ -43,8 +43,8 @@ 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(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"