Android DatePickerDialog: Set min and max date for selection

46,564

Solution 1

Try this method

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Calendar calendar = Calendar.getInstance();
    int year    = calendar.get(Calendar.YEAR);
    int month   = calendar.get(Calendar.MONTH);
    int day     = calendar.get(Calendar.DAY_OF_MONTH);

    DatePickerDialog dialog = new DatePickerDialog(getContext(), listener, year, month, day);
    Field mDatePickerField;
    try {
            mDatePickerField = dialog.getClass().getDeclaredField("mDatePicker");
            mDatePickerField.setAccessible(true);
    } catch (Exception e) {
            e.printStackTrace();
    }
    dialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
    return dialog;
}

instead of your

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    Calendar calendar = Calendar.getInstance();
    int year    = calendar.get(Calendar.YEAR);
    int month   = calendar.get(Calendar.MONTH);
    int day     = calendar.get(Calendar.DAY_OF_MONTH);

    DatePickerDialog dialog = new DatePickerDialog(getContext(), listener, year, month, day);
    dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
    return dialog;
}

EDIT1:

I have also faced this issue that user can select not-selectable dates in Android L 5.0.2. Currently there is bug reported here. It is solved in Android L 5.1.0.

For temporary solution of this issue you can compare selected date with current system date and put some condition based on that. I used this as my workaround

EDIT2:

add onDateSent() method in DatePickerDialogFragment and just check if it's earlier than the date you set in setMinDate(). If so, then just show the DatePickerDialog again.

final long today = System.currentTimeMillis() - 1000;

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, monthOfYear, dayOfMonth);
            //If user tries to select date in past (or today)
            if (calendar.getTimeInMillis() < today)
            {
                //Make them try again
               DatePickerDialogFragment fragment = new DatePickerDialogFragment();
               fragment.setListener(dateSetListener);
               fragment.show(getSupportFragmentManager(), "Choose booking date");
               Toast.makeText(this, "Invalid date, please try again", Toast.LENGTH_LONG).show();
            }
            else
            {
                //success
            }
}

Solution 2

Get System Time and subtract 1 second from It

 @Override
 public Dialog onCreateDialog(Bundle savedInstanceState) {
    Calendar calendar = Calendar.getInstance();
    int year    = calendar.get(Calendar.YEAR);
    int month   = calendar.get(Calendar.MONTH);
    int day     = calendar.get(Calendar.DAY_OF_MONTH);

     dialog = new DatePickerDialog(act, listener, year, month, day);
     dialog.getDatePicker().setMinDate(System.currentTimeMillis() -1000);
     return dialog;
 }

Solution 3

dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());

Solution 4

Above API 11 For min date you can use

android:minDate="mm/dd/yyyy" or setMinDate(long time) For Max date

android:maxDate="mm/dd/yyyy" // In XML

setMaxDate(new Date().getTime());// Current time

Solution 5

I set the minimum date using the method to the current year which is 2020-05-20 like this

datePickerDialog.getDatePicker().setMinDate(calendar.getTimeInMillis());

The moment you click the date picker it displays 2020 as the minimum year

I hope the answer helps.

Share:
46,564

Related videos on Youtube

Abdullah
Author by

Abdullah

Updated on July 09, 2022

Comments

  • Abdullah
    Abdullah almost 2 years

    I know there are quite a lot of question for this but none of the solutions are working for me, so this question. I want to restrict user to select date before today, but am not able to do so.

    public class DatePickerDialogFragment extends DialogFragment {
    
        private OnDateSetListener listener;
    
        public void setListener(OnDateSetListener listener) {
            this.listener = listener;
        }
    
        @NonNull
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            Calendar calendar = Calendar.getInstance();
            int year    = calendar.get(Calendar.YEAR);
            int month   = calendar.get(Calendar.MONTH);
            int day     = calendar.get(Calendar.DAY_OF_MONTH);
    
            DatePickerDialog dialog = new DatePickerDialog(getContext(), listener, year, month, day);
            dialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
            return dialog;
        }
    }
    

    I am showing it as:

    DatePickerDialogFragment fragment = new DatePickerDialogFragment();
    fragment.setListener(dateSetListener);
    fragment.show(getSupportFragmentManager(), "Choose booking date");
    

    I want the user should not be able to select date before today. As you can see I called setMinDate() method with today's time but it as no effect. The dialog shows dates before today as grayed but selectable.

    I also tried to sub-class DatePickerDialog and override onDateChanged as suggested in some stackoverflow answers but without any success.

    • cuasodayleo
      cuasodayleo about 8 years
      not smart complete but onDateSet, should compare result with min and max value
    • Rethinavel
      Rethinavel almost 8 years
      @Abdullah Did you find any work out for this..?
    • Abdullah
      Abdullah almost 8 years
      @RethinavelPillai I ended up doing what is mentioned in the accepted post.
    • Manohar
      Manohar almost 7 years
      check out mycustom datepickerdialog github.com/Redman1037/EightFoldsDatePickerDialog
  • Abdullah
    Abdullah over 8 years
    I am calling setMinDate() but it has no effect.
  • Abdullah
    Abdullah over 8 years
    Thanks for the update. Eventually I ended up doing the same.
  • Ahmad F
    Ahmad F over 6 years
    Although your code snippet might solve the issue, you should describe what’s the purpose of your code (how it solves the problem). Furthermore, you might want to check stackoverflow.com/help/how-to-answer
  • Ashish Sharma
    Ashish Sharma over 3 years
    Please provide an explanation for your code.
  • Kiran Kumar S
    Kiran Kumar S over 3 years
    @AshishSharma you can set the minimum date for selection by getting the date from the calendar2 or to set the minimum date programatically by calendar2.set(2021, 1, 3) and set the maximum date for selection by setting the calendar3.set(2021, 3, 3) by programatically or u can also set by month,day, year by specifying month,day,year for eg. i'm adding one moth month maximum for calender3 date calendar3.add(Calendar.MONTH, 1);