henninghall / react-native-date-picker

React Native Date Picker is datetime picker for Android and iOS. It includes date, time and datetime picker modes. The datepicker is customizable and is supporting different languages. It's written with native code to achieve the best possible look, feel and performance.
MIT License
2.25k stars 346 forks source link

NullPointerException in Android at java.util.Calendar.setTime (Calendar.java:1749) #37

Closed hwde closed 5 years ago

hwde commented 5 years ago

It looks like the Picker can cause a NullPointerException if a "far future" date is picked, i.e. set the year to 2100 - maybe related to a Android/Java Date/Time limitation?. Maybe the issue is not the "pick" but the the update of the picker after the picked value has been send to the app.

Stack trace is:

java.lang.NullPointerException: 
  at java.util.Calendar.setTime (Calendar.java:1749)
  at java.text.SimpleDateFormat.format (SimpleDateFormat.java:981)
  at java.text.SimpleDateFormat.format (SimpleDateFormat.java:974)
  at java.text.DateFormat.format (DateFormat.java:341)
  at com.henninghall.date_picker.wheels.Wheel.setValue (Wheel.java:74)
  at com.henninghall.date_picker.wheelFunctions.SetDate.apply (SetDate.java:17)
  at com.henninghall.date_picker.PickerView.applyOnAllWheels (PickerView.java:208)
  at com.henninghall.date_picker.PickerView.setDate (PickerView.java:137)
  at com.henninghall.date_picker.DatePickerManager.onAfterUpdateTransaction (DatePickerManager.java:84)
  at com.henninghall.date_picker.DatePickerManager.onAfterUpdateTransaction (DatePickerManager.java:15)
  at com.facebook.react.uimanager.ViewManager.updateProperties (ViewManager.java:33)
  at com.facebook.react.uimanager.NativeViewHierarchyManager.createView (NativeViewHierarchyManager.java:269)
  at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute (UIViewOperationQueue.java:200)
  at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.dispatchPendingNonBatchedOperations (UIViewOperationQueue.java:1085)
  at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded (UIViewOperationQueue.java:1056)
  at com.facebook.react.uimanager.GuardedFrameCallback.doFrame (GuardedFrameCallback.java:29)
  at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame (ReactChoreographer.java:134)
  at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame (ChoreographerCompat.java:105)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:909)
  at android.view.Choreographer.doCallbacks (Choreographer.java:723)
  at android.view.Choreographer.doFrame (Choreographer.java:655)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:897)
  at android.os.Handler.handleCallback (Handler.java:789)
  at android.os.Handler.dispatchMessage (Handler.java:98)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6944)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run (Zygote.java:327)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)
henninghall commented 5 years ago

Thanks for reporting this, I will have a look at it!

LuisBonsembiante commented 5 years ago

Any news about that....the library doesnt work

henninghall commented 5 years ago

@LuisBonsembiante I haven't had time to look into this yet. Feel free to fix it yourself, pull requests are welcome 🙂

henninghall commented 5 years ago

@LuisBonsembiante @hwde I have tried but I don't manage to reproduce the crash. Could you send the code of how you are using the component, including the props so I can try the same setup? Also, what version of the lib are you using?

hwde commented 5 years ago

I use version 2.3.0, this way:

    constructor(props) {
        super(props);

        this.state =
        {
            value           : this.props.value,
            selectedValue   : null,
        };
    }
    renderPicker() {
        return (
            <DatePicker
                date={this.state.selectedValue == null ? this.state.value : this.state.selectedValue}
        onDateChange={date => this.onSelectValue(date)}
                mode={'date'} />
        );
    }

And my component gets called with some date strings, i.e. "1999-12-24". I tried to debug the issue myself to write a pull request, but I was unable to "break" at a breakpoint inside java code. Will give it another try with a new sample project next days.

hwde commented 5 years ago

Funny, I am now able to "break" my app, the crash happens when "this" is a AmPmWheel, now at line Wheel.java#82:

if(picker.getValue() == 0) picker.setValue(index);

picker.getValue() is 0, and "index" is 0 too. But I can't see why picker.setValue(0) crashes. Maybe it is because a "AmPmWheel" is not visible when only "date" selection is done?

henninghall commented 5 years ago

And my component gets called with some date strings, i.e. "1999-12-24".

Hmm, you should call the date picker with Date objects, not strings. Try changing it!

Since you are not using maximumDate, the default for date mode is 2100. Try to set maximumDate prop to something higher if you expect values above 2100. For instance:

const maxDate = new Date(2110,1,1)
...
<DatePicker
    maximumDate={maxDate}
...


... , but I was unable to "break" at a breakpoint inside java code.

If you are running the example app in this repo you need to set the breakpoints in example/node_modules/react-native-date-picker/android/...

picker.getValue() is 0, and "index" is 0 too. But I can't see why picker.setValue(0) crashes. Maybe it is because a "AmPmWheel" is not visible when only "date" selection is done?

Yeah probably.

hwde commented 5 years ago

Sorry, my mistake. I don't use strings for the value. I use something like: value={new Date("1999-12-24")}

I tried as you suggested and added the maximumDate={maxDate}, but it still crashes.

hwde commented 5 years ago

btw.: I now tried with:

const maxDate = new Date(); ... <DatePicker maximumDate={maxDate} ...

but it renders still with a maximum year of 2100, does maximumDate works with Android?

henninghall commented 5 years ago

Yes maximumDate should be supported on android! Just to be sure, this code actually gets your app to crash?


const maxDate = new Date(2110,1,1)

export default class Example {

   state = {
      date: new Date(2100, 1, 1)
   }

   render(){
       return (
           <DatePicker
               date={this.state.date}
               maximumDate={maxDate}
               mode={'date'}
               setDate={date => this.setState({ date })}
           />
       )
   }

}

What phone model are you using? Thanks a lot for your help!

hwde commented 5 years ago

It looks like this is a react-native race-condition ... somehow. I am unable to reproduce it in a sample app. I need some time to look it more deeper. I'll get back asap.

henninghall commented 5 years ago

Thanks a lot! 🙂

henninghall commented 5 years ago

Since we are not able to reproduce this, I am closing this issue. I'll reopen if anyone finds a way to reproduce this in an example app.