Skip to content

fix(date): keep birthdate within the age range when refDate is a leap day - #4208

Merged
ST-DDT merged 3 commits into
faker-js:nextfrom
kevin9327:fix/birthdate-leap-day-age
Oct 28, 2026
Merged

ST-DDT merged 3 commits into
faker-js:nextfrom
kevin9327:fix/birthdate-leap-day-age

Conversation

@kevin9327

Copy link
Copy Markdown
Contributor

faker.date.birthdate({ mode: 'age' }) builds its range by moving refDate back by whole years with setUTCFullYear. When refDate is February 29 and the target year is a common year, setUTCFullYear rolls the date over to March 1. That puts the latest birthdate one day too late, so the result can be one year younger than min:

const refDate = new Date(Date.UTC(2024, 1, 29, 12));
// 20,000 draws of faker.date.birthdate({ mode: 'age', min: 18, max: 18, refDate })
// 31 are born on 2006-03-01 and are 17 on refDate (their 18th birthday is 2024-03-01)

The fix moves a February 29 refDate to February 28 when the target year has no leap day, for both ends of the range. The latest birthdate becomes 2006-02-28 (18 on refDate), and the earliest becomes 1943-03-01 instead of 1943-03-02 for max: 80 (still 80 on refDate, so it was wrongly excluded). Other dates, and mode: 'year', are unchanged.

Two tests use a fixed randomizer (like the past/future range tests) to pin each end of the range for a leap-day refDate. Both fail on next (2006-03-01 and 1943-03-02) and pass with the fix. test/modules/date.spec.ts passes (711 tests) and no snapshots change.

AI-assisted: I directed the investigation and reviewed and verified the change myself.

@kevin9327
kevin9327 requested a review from a team as a code owner October 26, 2026 06:26
@netlify

netlify Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for fakerjs ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit bbb1eb4
🔍 Latest deploy log https://app.netlify.com/projects/fakerjs/deploys/6ae054097a3cabef3e943c31
😎 Deploy Preview https://deploy-preview-4208.fakerjs.dev
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov

codecov Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.18%. Comparing base (b13a487) to head (bbb1eb4).

Additional details and impacted files
@@           Coverage Diff           @@
##             next    #4208   +/-   ##
=======================================
  Coverage   99.18%   99.18%           
=======================================
  Files        1179     1179           
  Lines        3941     3947    +6     
  Branches      711      698   -13     
=======================================
+ Hits         3909     3915    +6     
  Misses         28       28           
  Partials        4        4           
Files with missing lines Coverage Δ
src/modules/date/birthdate.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ST-DDT ST-DDT added c: bug Something isn't working p: 1-normal Nothing urgent s: pending triage Pending Triage m: date Something is referring to the date module labels Oct 26, 2026
@ST-DDT ST-DDT added this to the v11.0 milestone Oct 26, 2026
Comment thread test/modules/date.spec.ts Resolved
Comment thread test/modules/date.spec.ts Resolved
@ST-DDT ST-DDT removed the s: pending triage Pending Triage label Oct 26, 2026
@kevin9327

Copy link
Copy Markdown
Contributor Author

Thanks! Switched the randomizer to MERSENNE_MAX_VALUE and applied the suggested comment in 6f51ed4. test/modules/date.spec.ts passes locally (711 tests).

@ST-DDT ST-DDT left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@ST-DDT

ST-DDT commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Does this also affect past/future? (If yes, maybe fix it in a follow-up PR)

@kevin9327

Copy link
Copy Markdown
Contributor Author

Yes, partly. past and future build their bounds with the same setUTCFullYear, so with a refDate of 2024-02-29 "1 year ago" becomes 2023-03-01 and "1 year ahead" 2025-03-01. Both bounds move by the same day, so the range keeps its length. Nothing breaks there the way the age check did in birthdate, but past({ years: { min: 1, max: 2 } }) can return 2023-02-28, which is less than a year before the refDate if you count Feb 28 as the anniversary (date-fns subYears clamps that way). If you'd like past/future to clamp to Feb 28 as well, I can open a follow-up PR with tests for it.

@ST-DDT

ST-DDT commented Oct 28, 2026

Copy link
Copy Markdown
Member

IMO birthdate and past/future should behave identical in that regard.

@kevin9327

Copy link
Copy Markdown
Contributor Author

Agreed. I opened #4215 so past and future clamp a leap-day refDate to Feb 28 the same way, with tests for each end of the range.

@ST-DDT
ST-DDT added this pull request to the merge queue Oct 28, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 28, 2026
@ST-DDT
ST-DDT added this pull request to the merge queue Oct 28, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 28, 2026
@ST-DDT
ST-DDT added this pull request to the merge queue Oct 28, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 28, 2026
@ST-DDT

ST-DDT commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Looks like we are getting some weak runners today.
(On Monday 26 PRs merged without a single failure, today we are at 3/3 failures)
I think i found a way to address this issue and will create a fix for it later.

@ST-DDT
ST-DDT added this pull request to the merge queue Oct 28, 2026
Merged via the queue into faker-js:next with commit a9d2058 Oct 28, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c: bug Something isn't working m: date Something is referring to the date module p: 1-normal Nothing urgent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants