From bd37df6ee72526922e980e9b1c5876abaf56b79f Mon Sep 17 00:00:00 2001 From: Huanyi Xie <74809554+xiehuanyi@users.noreply.github.com> Date: Sat, 10 Oct 2026 14:48:53 +0300 Subject: [PATCH] fix: preserve decimal digits when truncating counts --- HISTORY.md | 4 ++++ README.md | 1 + bower.json | 3 ++- humanize-duration.js | 20 ++++++++++++++++++-- package.json | 3 ++- test/humanizer.js | 14 ++++++++++++++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 637be92..6393c78 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,7 @@ +# Unreleased + +- fix: preserve decimal digits when truncating with `maxDecimalPoints` + # 3.35.0 / 2026-09-10 - new: Azerbaijani support (`az`) diff --git a/README.md b/README.md index 283c378..f42cc35 100644 --- a/README.md +++ b/README.md @@ -455,6 +455,7 @@ Lovingly made by [Evan Hahn](https://evanhahn.com/) with help from: - [Kristijan Jesenski](https://github.com/kjesenski) for Slovenian support - [Michal Karzel](https://github.com/Misioka) for improving Arabic support - [Mikias Menjeta](https://github.com/OMikiasO) for Amharic support +- [Huanyi Xie](https://github.com/xiehuanyi) for fixing decimal truncation Licensed under the permissive [Unlicense](https://unlicense.org/). Enjoy! diff --git a/bower.json b/bower.json index 119f3f9..ef6dfc9 100644 --- a/bower.json +++ b/bower.json @@ -34,7 +34,8 @@ "Michal Karzel (https://github.com/Misioka)", "Batmend Ganbaatar (https://github.com/theironbatka)", "Mikias Menjeta (https://github.com/OMikiasO)", - "Marko Plaznik (https://github.com/ohicee)" + "Marko Plaznik (https://github.com/ohicee)", + "Huanyi Xie (https://github.com/xiehuanyi)" ], "version": "3.35.0", "description": "Convert millisecond durations to English and many other languages.", diff --git a/humanize-duration.js b/humanize-duration.js index f2fe2b3..d969dc0 100644 --- a/humanize-duration.js +++ b/humanize-duration.js @@ -1330,6 +1330,23 @@ throw new Error("No language found."); } + /** + * @internal + * @param {number} count + * @param {number} decimalPoints + * @returns {number} + */ + function truncateCount(count, decimalPoints) { + var parts = count.toString().split("e"); + var shifted = Number( + parts[0] + "e" + ((Number(parts[1]) || 0) + decimalPoints) + ); + if (!isFinite(shifted)) return count; + + parts = Math.floor(shifted).toString().split("e"); + return Number(parts[0] + "e" + ((Number(parts[1]) || 0) - decimalPoints)); + } + /** * @internal * @param {Piece} piece @@ -1366,8 +1383,7 @@ var normalizedUnitCount = maxDecimalPoints === void 0 ? unitCount - : Math.floor(unitCount * Math.pow(10, maxDecimalPoints)) / - Math.pow(10, maxDecimalPoints); + : truncateCount(unitCount, maxDecimalPoints); var countStr = normalizedUnitCount.toString(); if (language._hideCountIf2 && normalizedUnitCount === 2) { diff --git a/package.json b/package.json index 6ead634..d5f9e80 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "Michal Karzel (https://github.com/Misioka)", "Batmend Ganbaatar (https://github.com/theironbatka)", "Mikias Menjeta (https://github.com/OMikiasO)", - "Marko Plaznik (https://github.com/ohicee)" + "Marko Plaznik (https://github.com/ohicee)", + "Huanyi Xie (https://github.com/xiehuanyi)" ], "version": "3.35.0", "description": "Convert millisecond durations to English and many other languages.", diff --git a/test/humanizer.js b/test/humanizer.js index 3d09c76..ec25c5b 100644 --- a/test/humanizer.js +++ b/test/humanizer.js @@ -162,6 +162,20 @@ describe("humanizer", function () { assert.strictEqual(h(7999), "7.999 seconds"); }); + it('preserves decimal digits when truncating with "maxDecimalPoints"', function () { + const h = humanizer({ units: ["s"], maxDecimalPoints: 2 }); + + assert.strictEqual(h(1150), "1.15 seconds"); + assert.strictEqual(h(2300), "2.3 seconds"); + assert.strictEqual(h(1159), "1.15 seconds"); + assert.strictEqual( + h(0.00115, { maxDecimalPoints: 8 }), + "0.00000115 seconds" + ); + assert.strictEqual(h(1150, { maxDecimalPoints: 309 }), "1.15 seconds"); + assert.strictEqual(h(1.15e24), "1.15e+21 seconds"); + }); + it('pluralizes based on the count rendered by "maxDecimalPoints"', function () { const h = humanizer({ maxDecimalPoints: 0 });