Skip to content

fix(android): allow dates before 1970 when only maximumDate is set - #1067

Open
huytdps13400 wants to merge 1 commit into
react-native-datetimepicker:masterfrom
huytdps13400:fix/android-min-date-before-epoch
Open

huytdps13400 wants to merge 1 commit into
react-native-datetimepicker:masterfrom
huytdps13400:fix/android-min-date-before-epoch

Conversation

@huytdps13400

Copy link
Copy Markdown

Summary

Fixes #935

On Android (API 26+), when maximumDate is set but minimumDate is not, the user can't pick a date before 1970-01-01. The picker snaps back to the epoch.

Root cause: if either bound is set, RNDatePickerDialogFragment installs an OnDateChangedListener that clamps the selected date to [Common.minDateWithTimeZone(args), Common.maxDateWithTimeZone(args)]. When maximumDate is missing, maxDateWithTimeZone returns Long.MAX_VALUE. When minimumDate is missing, minDateWithTimeZone returned 0, which is the Unix epoch, so every earlier date was clamped to 1970-01-01.

Change: minDateWithTimeZone now returns Long.MIN_VALUE when minimumDate is not set, the same way maxDateWithTimeZone returns Long.MAX_VALUE. Both call sites (RNDatePickerDialogFragment and RNMaterialDatePicker) only use the value for clamping or after checking that the key exists. The picker's own lower bound (setMinDate(RNConstants.DEFAULT_MIN_DATE)) is unchanged.

Test Plan

I verified this with a local Robolectric test, which I did not include because the repo has no Android unit test setup. I can add it if you want. The test shows RNDatePickerDialogFragment with value = 1970-01-02 and maximumDate = 2006-01-01, calls DatePicker#updateDate(1965, 5, 15) (which fires the clamping listener), and checks the date the picker shows. It ran on SDK 26, 28, 30, 33, 34 and 35.

Case Before After
only maximumDate set, select 1965-06-15 1970-01-01 1965-06-15
minimumDate 1990-01-01 and maximumDate set, select 1965-06-15 1990-01-01 1990-01-01 (still clamped)

What's required for testing (prerequisites)?

An Android device or emulator on API 26 or higher.

What are the steps to reproduce (after prerequisites)?

Use mode="date", value={new Date(1970, 0, 2)}, maximumDate={new Date(2006, 0, 1)} and no minimumDate, then try to select a year before 1970.

Compatibility

OS Implemented
iOS ❌
Android ✅

Checklist

  • I have tested this on a device and a simulator (verified with Robolectric only, see above)
  • I added the documentation in README.md (not needed)
  • I updated the typed files (TS and Flow) (no API change)
  • I added a sample use of the API in the example project (example/App.js) (not needed)
  • I have added automated tests, either in JS or e2e tests, as applicable (local Robolectric test, see above)

This fix was prepared with AI assistance (Claude Code) and verified locally with the tests above.

🤖 Generated with Claude Code

When only maximumDate is provided, the date change listener clamps the
selected date between minDateWithTimeZone and maxDateWithTimeZone. Without a
minimumDate, minDateWithTimeZone returned 0 (the Unix epoch), so any earlier
date snapped back to 1970-01-01. Return Long.MIN_VALUE instead, mirroring
maxDateWithTimeZone returning Long.MAX_VALUE when maximumDate is not set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

Unable to select a date earlier than Unix epoch when only a maximum date is provided on Android

1 participant