Skip to content

fix: return NaN from diff() when an operand is an Invalid Date - #3216

Open
yu2971512385-ui wants to merge 1 commit into
iamkun:devfrom
yu2971512385-ui:fix/diff-invalid-date-nan
Open

yu2971512385-ui wants to merge 1 commit into
iamkun:devfrom
yu2971512385-ui:fix/diff-invalid-date-nan

Conversation

@yu2971512385-ui

Copy link
Copy Markdown

Fixes #3186.

The bug

monthDiff in src/utils.js ends with || 0:

return +(-(wholeMonthDiff + ((b - anchor) / (c ? (anchor - anchor2) : (anchor2 - anchor)))) || 0)

When one operand is an Invalid Date, the arithmetic is NaN, and NaN || 0 collapses it to 0. So the month-based units silently return 0 instead of NaN:

dayjs('2018-08-08').diff(dayjs('invalid'), 'month', true) // 0, expected NaN
dayjs('2018-08-08').diff(dayjs('invalid'), 'year',  true) // 0, expected NaN

Every other unit already returns NaN for an Invalid Date operand (they go through plain millisecond arithmetic), and moment.js returns NaN here too — so 'month' | 'quarter' | 'year' are inconsistent.

The fix

Compute the value once and only normalize -0 to 0, letting NaN propagate to diff() unchanged:

const result = -(wholeMonthDiff + ((b - anchor) / (c ? (anchor - anchor2) : (anchor2 - anchor))))
return result === 0 ? 0 : result

Behaviour for valid dates is unchanged (-0 is still normalized to 0).

Tests

Added a Difference case asserting diff with an Invalid Date operand is NaN (not 0) for month, quarter and year, in both directions and for the float variants. Verified it fails on the current source and passes with the fix.

🤖 Generated with Claude Code

`monthDiff` ended with `|| 0`, which collapses the `NaN` produced by an Invalid
Date operand into `0`. As a result `diff(invalid, 'month' | 'quarter' | 'year')`
(and their `float` variants) returned `0` instead of `NaN`, unlike every other
unit and unlike moment.js.

Compute the value once and only normalize `-0` to `0`, letting `NaN` propagate
to `diff()` unchanged.

Fixes iamkun#3186

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

diff(..., 'year'|'month', true) returns 0 instead of NaN for an Invalid Date operand

1 participant