DatePicker.setMinDate(long minDate) throws IllegalArgumentException: Time not between
android, datepicker, datepickerdialog
Solution
The problem was that hours, minutes, seconds and milliseconds of the calendars that I was using for setting the `DatePicker`'s `minDate` and `maxDate` got set to the values correspondent to what time it was when `Calendar.getInstance()` was called. And when I passed the day, month and year to the constructor of `DatePickerDialog`, the dates were the same, but the milliseconds differed. So it could happen that the milliseconds set in maxDate were smaller than the milliseconds set in the `DatePicker`'s current time, therefore the date the `DatePicker` was supposed to show was evaluated as bigger than `maxDate` (even though it was still the same day, just with some more milliseconds)... And similarly for `minDate`.
I hope it's understandable.
So what helped was to set the calendars to the last millisecond of the day when using them for setting `maxDate` and to the first millisecond of the day when using them for setting `minDate`. Like so:
(Just a piece of code from the `else` clause.)
dpd.setTitle(getString(R.string.end_of_interval));
cal.add(Calendar.MONTH, 6);
cal.set(Calendar.HOUR_OF_DAY, cal.getMaximum(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, cal.getMaximum(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal.getMaximum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal.getMaximum(Calendar.MILLISECOND));
dpd.getDatePicker().setMaxDate(cal.getTimeInMillis());
cal.set(someTimeDuringYear1, someTimeDuringMonth1 - 1, someTimeDuringDay1);
cal.set(Calendar.HOUR_OF_DAY, cal.getMinimum(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, cal.getMinimum(Calendar.MINUTE));
cal.set(Calendar.SECOND, cal.getMinimum(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, cal.getMinimum(Calendar.MILLISECOND));
dpd.getDatePicker().setMinDate(cal.getTimeInMillis());
Hope it will be helpful to someone.
Also if someone comes up with a more elegant solution, please let me know.
Problem
I have a time interval consisting of a beginning and an end date. I have a way of letting the user set these dates through DatePickerDialogs. Here is the code of the method that creates and shows the dialogs: ``` private void editInterval(boolean beginning) { DatePickerDialog dpd; Calendar cal = Calendar.getInstance(); if (beginning) { dpd = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { someTimeDuringYear1 = year; someTimeDuringMonth1 = monthOfYear + 1; someTimeDuringDay1 = dayOfMonth; Calendar cal1 = Calendar.getInstance(); cal1.set(Calendar.YEAR, year); cal1.set(Calendar.MONTH, monthOfYear); cal1.set(Calendar.DAY_OF_MONTH, dayOfMonth); Calendar cal2 = Calendar.getInstance(); cal2.set(Calendar.YEAR, someTimeDuringYear2); cal2.set(Calendar.MONTH, someTimeDuringMonth2); cal2.set(Calendar.DAY_OF_MONTH, someTimeDuringDay2); if (cal1.getTimeInMillis() > cal2.getTimeInMillis()) { someTimeDuringYear2 = someTimeDuringYear1; someTimeDuringMonth2 = someTimeDuringMonth1; someTimeDuringDay2 = someTimeDuringDay1; } updateSomeTimeDuring(); editDepartureInterval(); } }, someTimeDuringYear1, someTimeDuringMonth1 - 1, someTimeDuringDay1); dpd.setTitle(getString(R.string.beginning_of_interval)); cal.add(Calendar.MONTH, 6); dpd.getDatePicker().setMaxDate(cal.getTimeInMillis()); cal.add(Calendar.MONTH, -6); cal.add(Calendar.DATE, 2); dpd.getDatePicker().setMinDate(cal.getTimeInMillis()); } else { dpd = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { someTimeDuringYear2 = year; someTimeDuringMonth2 = monthOfYear + 1; someTimeDuringDay2 = dayOfMonth; updateSomeTimeDuring(); editDepartureInterval(); } }, someTimeDuringYear2, someTimeDuringMonth2 - 1, someTimeDuringDay2); dpd.setTitle(getString(R.string.end_of_interval)); cal.add(Calendar.MONTH, 6); dpd.getDatePicker().setMaxDate(cal.getTimeInMillis()); cal.set(someTimeDuringYear1, someTimeDuringMonth1 - 1, someTimeDuringDay1); dpd.getDatePicker().setMinDate(cal.getTimeInMillis()); } dpd.show(); dpd.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); } ``` The value of the `beginning` variable determines whether the user has chosen to edit the beginning or end date of the interval. Those `someTimeDuringYear1` and similar are member variables related to the beginning date, `someTimeDuringYear2` and similar are related to the end date of the interval. All of them are pre-set before this dialog is ever created and shown. The exception is thrown while editing both the beginning and the end interval. Let's say I choose to edit the interval's end date. Everything works perfectly until I set the date to the last date that I am allowed to. If I do that and confirm, everything still seems fine, but when I try to edit the interval's end date again, the application crashes and the exception is thrown. (The same thing happens if I set the interval's beginning date to the last allowed date and then try to edit it again.) Here is the log from LogCat: ``` 03-28 17:18:16.901: E/AndroidRuntime(6112): FATAL EXCEPTION: main 03-28 17:18:16.901: E/AndroidRuntime(6112): java.lang.IllegalArgumentException: Time not between Sat Mar 30 17:18:16 CET 2013 and Sat Sep 28 17:18:16 CEST 2013 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.widget.CalendarView.goTo(CalendarView.java:805) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.widget.CalendarView.setMinDate(CalendarView.java:487) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.widget.DatePicker.setMinDate(DatePicker.java:315) 03-28 17:18:16.901: E/AndroidRuntime(6112): at com.skypicker.android.MainActivity.editInterval(MainActivity.java:344) 03-28 17:18:16.901: E/AndroidRuntime(6112): at com.skypicker.android.MainActivity.access$10(MainActivity.java:296) 03-28 17:18:16.901: E/AndroidRuntime(6112): at com.skypicker.android.MainActivity$5.onClick(MainActivity.java:261) 03-28 17:18:16.901: E/AndroidRuntime(6112): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:924) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.widget.AdapterView.performItemClick(AdapterView.java:292) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.widget.AbsListView.performItemClick(AbsListView.java:1063) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2519) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.widget.AbsListView$1.run(AbsListView.java:3173) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.os.Handler.handleCallback(Handler.java:605) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.os.Handler.dispatchMessage(Handler.java:92) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.os.Looper.loop(Looper.java:137) 03-28 17:18:16.901: E/AndroidRuntime(6112): at android.app.ActivityThread.main(ActivityThread.java:4424) 03-28 17:18:16.901: E/AndroidRuntime(6112): at java.lang.reflect.Method.invokeNative(Native Method) 03-28 17:18:16.901: E/AndroidRuntime(6112): at java.lang.reflect.Method.invoke(Method.java:511) 03-28 17:18:16.901: E/AndroidRuntime(6112): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787) 03-28 17:18:16.901: E/AndroidRuntime(6112): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554) 03-28 17:18:16.901: E/AndroidRuntime(6112): at dalvik.system.NativeStart.main(Native Method) ``` I have been looking for answers and trying to come up with a solution all afternoon. Any help is appreciated. Thank you. PS: This is the first question I ever ask here, so I apologize if there is something wrong about it. I'll be happy to provide any missing information about what's happening. EDIT: Strangely enough, even though the problem raises on the line when I try to set the `minDate`, it actually seems to be that the date is "bigger" than the `maxDate`. The reason that I have for believing this is that if I pass `someTimeDuringDay2 - 1` instead of `someTimeDuringDay2` to the `DatePickerDialog`'s constructor, the problem is gone. But then "day" field in the `DatePicker` is really by one smaller than I want it to be. I need it to be set to `someTimeDuringDay2` when the `DatePickerDialog` is shown, not to `someTimeDuringDay2 - 1`. But it seems to have a problem when the date is the same as its `maxDate`.