From b9526a93d6c42712d983137422c8535eb3bc2fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Tabille=20Manjabosco?= Date: Thu, 30 Nov 2017 13:43:55 -0200 Subject: [PATCH] Add full support for negative numbers closes #103 --- index.js | 41 +++++++++++++++++++----------------- readme.md | 5 +++++ tests.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 85 insertions(+), 23 deletions(-) diff --git a/index.js b/index.js index a1c796b..7229750 100644 --- a/index.js +++ b/index.js @@ -111,16 +111,17 @@ function parse(str) { */ function fmtShort(ms) { - if (ms >= d) { + var msAbs = Math.abs(ms); + if (msAbs >= d) { return Math.round(ms / d) + 'd'; } - if (ms >= h) { + if (msAbs >= h) { return Math.round(ms / h) + 'h'; } - if (ms >= m) { + if (msAbs >= m) { return Math.round(ms / m) + 'm'; } - if (ms >= s) { + if (msAbs >= s) { return Math.round(ms / s) + 's'; } return ms + 'ms'; @@ -135,25 +136,27 @@ function fmtShort(ms) { */ function fmtLong(ms) { - return ( - plural(ms, d, 'day') || - plural(ms, h, 'hour') || - plural(ms, m, 'minute') || - plural(ms, s, 'second') || - ms + ' ms' - ); + var msAbs = Math.abs(ms); + if (msAbs >= d) { + return plural(ms, msAbs, d, 'day'); + } + if (msAbs >= h) { + return plural(ms, msAbs, h, 'hour'); + } + if (msAbs >= m) { + return plural(ms, msAbs, m, 'minute'); + } + if (msAbs >= s) { + return plural(ms, msAbs, s, 'second'); + } + return ms + ' ms'; } /** * Pluralization helper. */ -function plural(ms, n, name) { - if (ms < n) { - return; - } - if (ms < n * 1.5) { - return Math.floor(ms / n) + ' ' + name; - } - return Math.ceil(ms / n) + ' ' + name + 's'; +function plural(ms, msAbs, n, name) { + var isPlural = msAbs >= n * 1.5; + return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); } diff --git a/readme.md b/readme.md index 4599dd6..bb76729 100644 --- a/readme.md +++ b/readme.md @@ -17,6 +17,9 @@ ms('1m') // 60000 ms('5s') // 5000 ms('1y') // 31557600000 ms('100') // 100 +ms('-3 days') // -259200000 +ms('-1h') // -3600000 +ms('-200') // -200 ``` ### Convert from Milliseconds @@ -24,6 +27,7 @@ ms('100') // 100 ```js ms(60000) // "1m" ms(2 * 60000) // "2m" +ms(-3 * 60000) // "-3m" ms(ms('10 hours')) // "10h" ``` @@ -32,6 +36,7 @@ ms(ms('10 hours')) // "10h" ```js ms(60000, { long: true }) // "1 minute" ms(2 * 60000, { long: true }) // "2 minutes" +ms(-3 * 60000, { long: true }) // "-3 minutes" ms(ms('10 hours'), { long: true }) // "10 hours" ``` diff --git a/tests.js b/tests.js index 89b9d9c..3e94007 100644 --- a/tests.js +++ b/tests.js @@ -65,10 +65,16 @@ describe('ms(string)', function() { expect(ms('.5ms')).to.be(0.5); }); - it('should work with numbers starting with -', function() { - expect(ms('-5')).to.be(-5); - expect(ms('-.5ms')).to.be(-0.5); - expect(ms('-0.5ms')).to.be(-0.5); + it('should work with negative integers', function() { + expect(ms('-100ms')).to.be(-100); + }); + + it('should work with negative decimals', function() { + expect(ms('-1.5h')).to.be(-5400000); + }); + + it('should work with negative decimals starting with "."', function() { + expect(ms('-.5h')).to.be(-1800000); }); }); @@ -108,6 +114,18 @@ describe('ms(long string)', function() { it('should work with decimals', function() { expect(ms('1.5 hours')).to.be(5400000); }); + + it('should work with negative integers', function() { + expect(ms('-100 milliseconds')).to.be(-100); + }); + + it('should work with negative decimals', function() { + expect(ms('-1.5 hours')).to.be(-5400000); + }); + + it('should work with negative decimals starting with "."', function() { + expect(ms('-.5 hr')).to.be(-1800000); + }); }); // numbers @@ -121,34 +139,54 @@ describe('ms(number, { long: true })', function() { it('should support milliseconds', function() { expect(ms(500, { long: true })).to.be('500 ms'); + + expect(ms(-500, { long: true })).to.be('-500 ms'); }); it('should support seconds', function() { expect(ms(1000, { long: true })).to.be('1 second'); expect(ms(1200, { long: true })).to.be('1 second'); expect(ms(10000, { long: true })).to.be('10 seconds'); + + expect(ms(-1000, { long: true })).to.be('-1 second'); + expect(ms(-1200, { long: true })).to.be('-1 second'); + expect(ms(-10000, { long: true })).to.be('-10 seconds'); }); it('should support minutes', function() { expect(ms(60 * 1000, { long: true })).to.be('1 minute'); expect(ms(60 * 1200, { long: true })).to.be('1 minute'); expect(ms(60 * 10000, { long: true })).to.be('10 minutes'); + + expect(ms(-1 * 60 * 1000, { long: true })).to.be('-1 minute'); + expect(ms(-1 * 60 * 1200, { long: true })).to.be('-1 minute'); + expect(ms(-1 * 60 * 10000, { long: true })).to.be('-10 minutes'); }); it('should support hours', function() { expect(ms(60 * 60 * 1000, { long: true })).to.be('1 hour'); expect(ms(60 * 60 * 1200, { long: true })).to.be('1 hour'); expect(ms(60 * 60 * 10000, { long: true })).to.be('10 hours'); + + expect(ms(-1 * 60 * 60 * 1000, { long: true })).to.be('-1 hour'); + expect(ms(-1 * 60 * 60 * 1200, { long: true })).to.be('-1 hour'); + expect(ms(-1 * 60 * 60 * 10000, { long: true })).to.be('-10 hours'); }); it('should support days', function() { expect(ms(24 * 60 * 60 * 1000, { long: true })).to.be('1 day'); expect(ms(24 * 60 * 60 * 1200, { long: true })).to.be('1 day'); expect(ms(24 * 60 * 60 * 10000, { long: true })).to.be('10 days'); + + expect(ms(-1 * 24 * 60 * 60 * 1000, { long: true })).to.be('-1 day'); + expect(ms(-1 * 24 * 60 * 60 * 1200, { long: true })).to.be('-1 day'); + expect(ms(-1 * 24 * 60 * 60 * 10000, { long: true })).to.be('-10 days'); }); it('should round', function() { expect(ms(234234234, { long: true })).to.be('3 days'); + + expect(ms(-234234234, { long: true })).to.be('-3 days'); }); }); @@ -163,30 +201,46 @@ describe('ms(number)', function() { it('should support milliseconds', function() { expect(ms(500)).to.be('500ms'); + + expect(ms(-500)).to.be('-500ms'); }); it('should support seconds', function() { expect(ms(1000)).to.be('1s'); expect(ms(10000)).to.be('10s'); + + expect(ms(-1000)).to.be('-1s'); + expect(ms(-10000)).to.be('-10s'); }); it('should support minutes', function() { expect(ms(60 * 1000)).to.be('1m'); expect(ms(60 * 10000)).to.be('10m'); + + expect(ms(-1 * 60 * 1000)).to.be('-1m'); + expect(ms(-1 * 60 * 10000)).to.be('-10m'); }); it('should support hours', function() { expect(ms(60 * 60 * 1000)).to.be('1h'); expect(ms(60 * 60 * 10000)).to.be('10h'); + + expect(ms(-1 * 60 * 60 * 1000)).to.be('-1h'); + expect(ms(-1 * 60 * 60 * 10000)).to.be('-10h'); }); it('should support days', function() { expect(ms(24 * 60 * 60 * 1000)).to.be('1d'); expect(ms(24 * 60 * 60 * 10000)).to.be('10d'); + + expect(ms(-1 * 24 * 60 * 60 * 1000)).to.be('-1d'); + expect(ms(-1 * 24 * 60 * 60 * 10000)).to.be('-10d'); }); it('should round', function() { expect(ms(234234234)).to.be('3d'); + + expect(ms(-234234234)).to.be('-3d'); }); });