fix: handle negative pluralization correctly#276
Open
artahir-dev wants to merge 1 commit intovercel:mainfrom
Open
fix: handle negative pluralization correctly#276artahir-dev wants to merge 1 commit intovercel:mainfrom
artahir-dev wants to merge 1 commit intovercel:mainfrom
Conversation
Author
d6b3c4e to
76b1a4a
Compare
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Bug Fix: Incorrect Pluralization for Negative Values at Rounding Threshold
Overview
This PR addresses a grammar inconsistency in the
format()function when used with the{ long: true }option. Specifically, negative millisecond values at exact rounding thresholds (e.g.,-1500ms) are incorrectly pluralized despite resolving to a magnitude of1.Affected Behavior:
Root Cause Analysis
The Problem
The existing pluralization logic in the
plural()helper function determines singular vs. plural forms by checking the absolute input value against a threshold before rounding occurs:Why This Fails
For negative values at the
.5threshold, JavaScript'sMath.round()exhibits asymmetric behavior:Math.round(1.5)→2(rounds away from zero)Math.round(-1.5)→-1(rounds toward zero, per IEEE 754 round-half-up)Execution trace for
ms(-1500, { long: true }):msAbs = Math.abs(-1500) = 1500n = 1000(seconds unit)isPlural = (1500 >= 1000 * 1.5)→true✅rounded = Math.round(-1500 / 1000) = Math.round(-1.5)→-1"-1 seconds"❌ (grammatically incorrect for magnitude of 1)The threshold check (
1500 >= 1500) passes because the raw absolute value meets the plural criterion, but the subsequent rounding reduces the magnitude to1, which should be singular.Proposed Solution
Implementation
Invert the logic flow: perform rounding first, then determine pluralization based on the rounded absolute value:
Why This Works
|rounded| = 1(e.g.,-1 second,1 minute)0 seconds,2 hours,-3 days)1takes singular formCorrectness Guarantees
Math.abs(rounded) !== 1ms = -1500-1false"-1 second"ms = -1501-2true"-2 seconds"ms = 15002true"2 seconds"ms = 10001false"1 second"ms = 00true"0 ms"(fallback)Comprehensive Test Coverage
Edge Case Validation
Math.round()-1000ms-1.0-11"-1 second"-1499ms-1.499-11"-1 second"-1500ms-1.5-11"-1 second"-1501ms-1.501-22"-2 seconds"1499ms1.49911"1 second"1500ms1.522"2 seconds"1501ms1.50122"2 seconds"Test Implementation
Added to
src/format.test.ts:Changes Summary
Modified Files
src/index.ts(2 lines changed)plural()(lines ~236-244)src/format.test.ts(new test cases)Backward Compatibility
✅ Fully backward compatible
.5thresholdsTechnical Background: JavaScript Rounding Behavior
JavaScript's
Math.round()implements round-half-up for positive numbers but round-toward-zero for negative numbers:This asymmetry is defined in ECMAScript spec § 21.3.2.28 and follows IEEE 754's round-half-up mode. The original threshold-based logic was designed for positive values and did not account for this asymmetric behavior in negative inputs.
Verification Steps
Local Testing
Manual Verification
Impact Assessment
Severity: Low (cosmetic grammar issue, no functional impact)
Likelihood: Low (requires exact threshold values)
User Impact: Improved UX for applications displaying negative time durations
Risk: Minimal (logic change is localized and well-tested)
References
Math.roundChecklist: