react-native-modal-datetime-picker
react-native-modal-datetime-picker copied to clipboard
iOS TimePicker - default date actually return the launch date
Environment
System: OS: macOS 11.1 CPU: (20) x64 Intel(R) Core(TM) i9-10910 CPU @ 3.60GHz Memory: 1.48 GB / 32.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 12.19.0 - ~/.volta/tools/image/node/12.19.0/bin/node Yarn: 1.22.5 - ~/.volta/tools/image/yarn/1.22.5/bin/yarn npm: 6.14.8 - ~/.volta/tools/image/node/12.19.0/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.10.1 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4 Android SDK: Not Found IDEs: Android Studio: 4.2 AI-202.7660.26.42.7351085 Xcode: 12.5/12E262 - /usr/bin/xcodebuild Languages: Java: 14.0.2 - /usr/bin/javac Python: 2.7.16 - /usr/bin/python npmPackages: @react-native-community/cli: Not Found react: Not Found react-native: Not Found react-native-macos: Not Found npmGlobalPackages: react-native: Not Found
Platforms
iOS
Versions
10.0.0
Description
When using the time picker using an interval (for example 30 minutes), whenever the user clicks "OK" without changing the date, it return the locally cached time. For a DatePicker it's usually not a problem (unless the user starts the app at 11.45 PM and launches the picker at 0.10 AM the next day for example, but it's a edge case) but for the TimePicker it is because it doesn't return the correct hour.
One solution would be to generate a new date whenever the modal opens up. In the case of the time picker on iOS, we'd need to draw an algorithm that generate the closest date using the current time and the interval as a constraint. It seems this bug is deep inside the iOS picker itself.
Reproducible Demo
Something as simple as this should do.
<DateTimePicker
isVisible={visible}
onConfirm={confirm}
onCancel={close}
mode={"time"}
date={(variant === "start" ? props.start : props.end) || undefined}
minuteInterval={30}
locale={"fr_FR"}
confirmTextIOS={"Confirm"}
cancelTextIOS={"Cancel"}
headerTextIOS={"Choose an hour"}
minimumDate={variant === "end" && props.start ? props.start : undefined}
maximumDate={variant === "start" && props.end ? props.end : undefined}
/>
Hey @rewieer ! :D
Can't test it now, but I'm wondering...
but for the TimePicker it is because it doesn't return the correct hour.
Does the returned value not match what is shown in the UI?
Hey :D That is the problem, the date returned is the one that is generated when the component is mounted. Looks like on iOS, clicking "OK" without selecting anything (using the default) return whatever was left before. But if I change from, for example, 2:30 to 3:00, confirm, then go back to 2:30, there it works. Will investigate more and eventually submit a PR :)
I'm getting the same issue.
I am having the same issue but resolved by the below code
<DateTimePickerModal isVisible={isDatePickerVisible} mode={containsTime ? "datetime" : "date"} minimumDate={new Date().setMinutes( new Date().getMinutes() + 5 )} date={new Date().setMinutes(new Date().getMinutes() + 5)} display="spinner" onConfirm={handleConfirm} onCancel={hideDatePicker} />
Returning one day less on IOS but working fine on Andorid.
Basically It's returning time in 24 hours format . So this is how I handled it.
<DateTimePickerModal isVisible={this.state.showDate} mode={"time"} onConfirm={this.onChangeDate} onCancel={this.hideDatePicker} date={new Date()} minuteInterval={1} />
below is my onChangeDate function where I handled this issue.
onChangeDate = (text: any) => {
let hours = parseInt(JSON.stringify(text).slice(12, 14)) - 6;
let minutes = parseInt(JSON.stringify(text).slice(15, 17)) - 30;
console.warn("befor", hours, text);
if (minutes < 0) {
hours = hours - 1;
minutes = 60 + minutes;
}
if (hours < 0) {
hours = 24 + hours;
}
if (hours > 12) {
hours = hours - 12;
console.warn(`Time is => ${hours}:${minutes} AM`);
} else {
console.warn(`Time is => ${hours}:${minutes} PM`);
}
this.hideDatePicker();
}
Now It's Working fine.
Having the same issue. Any updates on this?
I was facing the same issue but I've come up with a solution. In the callback function for onConfirm, custom logic is dependent on the minuteInterval
const handleConfirm = (date: Date) => {
const minute =
Math.floor(date.getMinutes() / MINUTE_INTERVAL) * MINUTE_INTERVAL;
const newDate = new Date(
date.getFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
minute,
);
// update component state
setStartTime(newDate);
};
Hope this helps :)
add date={new Date()} See below;
return (
<DateTimePickerModal
mode="time"
isVisible={visible}
minimumDate={minDate ? minDate : new Date()}
date={minDate ? minDate : new Date()}
onChange={onChange}
is24Hour={true}
minuteInterval={minuteInterval}
maximumDate={maxDate}
locale={Localization.locale}
confirmTextIOS={${t(
Confirm)}
}
cancelTextIOS={${t(
Cancel)}
}
onConfirm={confirmHandler}
onCancel={cancelHandler}
textColor="black"
/>
);
Returning one day less on IOS but working fine on Android.
I have the same issue. How do I fix it?