datetimepicker icon indicating copy to clipboard operation
datetimepicker copied to clipboard

minimumDate prop working incorrect

Open kot-ezhva opened this issue 8 months ago • 5 comments

Bug report

I want to select a start date and an end date (for an event). For this purpose I set minimumDate in the second DatePicker.

  1. The second DatePicker does not trigger the onChange event, but visually changes the date. This can be fixed by tracking the negative difference between dates and setting the end date programmatically. Code below:
useEffect(() => {
  const diff = dayjs(end).diff(dayjs(start));
  if (diff < 0) {
    setEnd(start)
  }
}, [start, end]);

Image

  1. Returning the start date to yesterday's date will change the minimumDate for the end date. And the Second DatePicker starts setting the date as new Date(). Image

Example screen full code:

import React, { useEffect, useState } from 'react';
import { StyleSheet, ScrollView } from 'react-native';
import { DateTimePicker, ThemedText, ThemedView } from '@/components';
import RNDateTimePicker, { DateTimePickerEvent } from '@react-native-community/datetimepicker';
import { Common } from '@/constants';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import dayjs from 'dayjs';
import { useAppTheme } from '@/hooks/useAppTheme';

export default function ExploreScreen() {
  const [start, setStart] = useState(new Date());
  const [end, setEnd] = useState(new Date());
  
  const { colors } = useAppTheme();
  const { bottom: safeBottomOffset } = useSafeAreaInsets();

  useEffect(() => {
    const diff = dayjs(end).diff(dayjs(start));
    if (diff < 0) {
      setEnd(start)
    }
  }, [start, end]);
  
  return (
    <ScrollView
      contentContainerStyle={[
        styles.scroll,
        { paddingBottom: styles.scroll.padding + safeBottomOffset }
      ]}
      keyboardDismissMode="on-drag"
      keyboardShouldPersistTaps="always"
    >
      <ThemedText>Start: {dayjs(start).toString()}</ThemedText>
      <ThemedText>End:   {dayjs(end).toString()}</ThemedText>

      <ThemedView style={[styles.date, { backgroundColor: colors.border }]}>
        <ThemedText>Start</ThemedText>
        <RNDateTimePicker
          value={start}
          mode="date"
          onChange={(_, date) => date && setStart(date)}
          accentColor={colors.brand}
        />
      </ThemedView>

      <ThemedView style={[styles.date, { backgroundColor: colors.border }]}>
        <ThemedText>End</ThemedText>
        <RNDateTimePicker
          value={end}
          mode="date"
          onChange={(_, date) => {
            if (date) {
              setEnd(date);
            }
          }}
          accentColor={colors.brand}
          minimumDate={start}
        />
      </ThemedView>
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  scroll: {
    padding: Common.spaces.md,
    gap: Common.spaces.md,
  },
  date: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    height: 52,
    paddingHorizontal: Common.spaces.md,
    borderRadius: Common.spaces.xs,
  },
});

kot-ezhva avatar Mar 11 '25 10:03 kot-ezhva

The same as mine. Which react version u are using? Natiwind?

marijang avatar Mar 11 '25 10:03 marijang

Question

I want to select a start date and an end date (for an event). For this purpose I set minimumDate in the second DatePicker.

Video preview how it (not) works

https://github.com/user-attachments/assets/ec8d73fd-c858-4b4b-bc1f-6753d0daba16

kot-ezhva avatar Mar 11 '25 10:03 kot-ezhva

The same as mine. Which react version u are using? Natiwind?

Nope.

"expo": "~52.0.35", "react": "18.3.1", "react-native": "0.76.7",

kot-ezhva avatar Mar 11 '25 10:03 kot-ezhva

I'm pretty sure this is a @react-native-community/datetimepicker issue, because I found a workaround that works. But it's stupid and wrong

Image Image

And now, if we repeat the steps from the video, we can see that the date works correctly and the one passed as value is displayed

kot-ezhva avatar Mar 11 '25 10:03 kot-ezhva

And now, if we repeat the steps from the video, we can see that the date works correctly and the one passed as value is displayed

@marijang try this. Works? )

kot-ezhva avatar Mar 11 '25 10:03 kot-ezhva

You have have to fork the source code fix it and do a PR. Even then they might not look at the PR until 6 months and when they do they will ask you to write 20+ unit tests, then reject it

i-can-code-this avatar Jun 28 '25 17:06 i-can-code-this

You have have to fork the source code fix it and do a PR. Even then they might not look at the PR until 6 months and when they do they will ask you to write 20+ unit tests, then reject it

I solved this problem for myself. You can see my comment above

kot-ezhva avatar Jun 28 '25 18:06 kot-ezhva

Right but its a hacky work around people will have to dig to find. the maintainers should properly address the issue in the source code not your application code. You should fork and make a PR if you have time and patience, and your source code should not be in the solution or else you would have to update and fix your fork every time the maintainer makes a changes which is a pain

i-can-code-this avatar Jun 29 '25 01:06 i-can-code-this

Right but its a hacky work around people will have to dig to find.

This is not a change in the source code, but a way to work with the current one. Those who seek will always find 😉

kot-ezhva avatar Jun 29 '25 10:06 kot-ezhva

Thats fucking stupid, if this was a medical industry the maintainers would be in prison 3x over. I dont want to spend my whole day staring at a screen, the maintainers should update their docs lazy bums

i-can-code-this avatar Jun 29 '25 14:06 i-can-code-this