97

How can I disable past dates in my Android date picker?

Here's the code that produces my DatePicker:

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DATE_DIALOG_ID:
        // set date picker as current date
        return new DatePickerDialog(this, datePickerListener, year, month,
                day);
    }
    return null;
}

private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() {
    public void onDateSet(DatePicker view, int selectedYear,
            int selectedMonth, int selectedDay) {
        year = selectedYear;
        month = selectedMonth+1;
        day = selectedDay;

        startdate.setText(new StringBuilder().append(day).append("-")
                .append(getMonth(month + 1)).append("-").append(year)
                .append(" "));
    }
};
Pikamander2
  • 7,332
  • 3
  • 48
  • 69
Addy
  • 1,105
  • 1
  • 7
  • 13
  • 4
    DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), date, myCalendar.get(Calendar.YEAR), myCalendar.get(Calendar.MONTH), myCalendar.get(Calendar.DAY_OF_MONTH)); datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000); datePickerDialog.show(); – Dilip Jan 31 '18 at 06:16
  • Thanks worked, by adding 'datePicker.minDate = System.currentTimeMillis() - 1000' – Annie Apr 22 '21 at 08:27

15 Answers15

261

You can do

datePicker.setMinDate(System.currentTimeMillis() - 1000);

which sets today's date as minimum date and all the past dates are disabled.

datePicker is an object of DatePicker if you are using an object of DatePickerDialog you can do

datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);

Note: setMinDate was introduced in API 11

Apoorv
  • 13,470
  • 4
  • 27
  • 33
  • Thanks for the response.. Where should I have to put this line ? – Addy May 20 '14 at 14:28
  • Where you create your `DatePicker` or `DatePickerDialog` object – Apoorv May 20 '14 at 14:29
  • 1
    Thank you for the answer. But when I used the above solution it gave me crash in my application. So I changed the "System.currentTimeMillis() - 1000" to "System.currentTimeMillis() - 10000" and my application worked perfectly. Can you please lemme know why I am getting crash on subtracting 1000 but not on 10000 – user3705697 Apr 16 '15 at 12:07
  • 3
    the previous dates are disabled but they can be selected :( – Sjd Nov 04 '16 at 13:58
  • how to set custom date as minimum date? Suppose I've two date pickers, one is start date and another in end date. How limit end date from start date? – Sourav Roy Nov 12 '16 at 06:54
  • 1
    this one also works fine for me **datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis())** then what is the difference between **setMinDate(System.currentTimeMillis()) and setMinDate(System.currentTimeMillis()-1000)** – RAJESH KUMAR ARUMUGAM Apr 18 '17 at 07:25
  • 7
    May I know the reason of having `-1000`? – Cheok Yan Cheng Nov 07 '18 at 12:45
  • Why -1000 ????? – Kunal Kalwar Jun 02 '22 at 12:57
  • 1
    It basically means the min date is 1 second ago. – Apoorv Jun 06 '22 at 17:38
20

This method will work properly.

//Get yesterday's date
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -1);

//Set yesterday time milliseconds as date pickers minimum date
DatePickerDialog datePickerDialog = new DatePickerDialog(context, myDateListener, year, month, day);
datePickerDialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
datePickerDialog.show();
Arvin Jayanake
  • 1,475
  • 3
  • 14
  • 26
13

With the Material Components Library just use the MaterialDatePicker and build your own DateValidator or you can just use the DateValidatorPointForward provided by the library.

Something like:

MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();

CalendarConstraints.DateValidator dateValidator = DateValidatorPointForward.now();
//if you need a custom date just use
//CalendarConstraints.DateValidator dateValidator = DateValidatorPointForward.from(yourDate);
constraintsBuilder.setValidator(dateValidator);
builder.setCalendarConstraints(constraintsBuilder.build());

MaterialDatePicker<Long> picker = builder.build();
picker.show(getSupportFragmentManager(), picker.toString());

enter image description here

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • I like the "here's some code, go figure it out" approach material.io took documenting this. https://github.com/material-components/material-components-android/blob/master/catalog/java/io/material/catalog/datepicker/DatePickerMainDemoFragment.java – lasec0203 Sep 13 '20 at 07:14
8

This is how I do it:

public class DatePickerFragment extends DialogFragment {
OnDateSetListener ondateSet;
Calendar c;
int year = 0, month = 0, day = 0;

public DatePickerFragment() {
}

public void setCallBack(OnDateSetListener ondate) {
    ondateSet = ondate;
}

public static DatePickerFragment newInstance(Bundle bundle) {
    DatePickerFragment myFragment = new DatePickerFragment();
    myFragment.setArguments(bundle);
    return myFragment;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    // final Calendar c = Calendar.getInstance();
//if else for null arguments
    if (getArguments() != null) {
        year = getArguments().getInt("year");
        month = getArguments().getInt("month");
        day = getArguments().getInt("day");
        c = Calendar.getInstance();
        c.set(year, month, day);

    } else {
        c = Calendar.getInstance();
        year = c.get(Calendar.YEAR);
        month = c.get(Calendar.MONTH);
        day = c.get(Calendar.DAY_OF_MONTH);
        Log.d("else", "else");
    }


    DatePickerDialog picker = new DatePickerDialog(getActivity(),
            ondateSet, year, month, day);
    picker.getDatePicker().setMinDate(c.getTime().getTime());
    Log.d("picker timestamp", c.getTime().getTime() + "");
    return picker;
}
}

This is how you instantiate the picker:

Bundle bundle = new Bundle();
        Calendar c = Calendar.getInstance();
        bundle.putInt("year", c.get(Calendar.YEAR));
        bundle.putInt("month", c.get(Calendar.MONTH));
        bundle.putInt("day", c.get(Calendar.DAY_OF_MONTH));
        DatePickerFragment fragment = DatePickerFragment
                .newInstance(bundle);
        fragment.setCallBack(dateSet);
        fragment.show(getActivity().getSupportFragmentManager(), null);

This is my implementation feel free to change it. Note that this code sets mindate as currnet date by default. Also the newInstance is important.

Illegal Argument
  • 10,090
  • 2
  • 44
  • 61
5

If you are using DatePicker

datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
4b0
  • 21,981
  • 30
  • 95
  • 142
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Yunnosch Jul 25 '21 at 07:46
4

Output

Calendar c = Calendar.getInstance();
DatePickerDialog dialog = new DatePickerDialog(context, new DatePickerDialog.OnDateSetListener() {
    @Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
        String _year = String.valueOf(year);
        String _month = (month+1) < 10 ? "0" + (month+1) : String.valueOf(month+1);
        String _date = dayOfMonth < 10 ? "0" + dayOfMonth : String.valueOf(dayOfMonth);
        String _pickedDate = year + "-" + _month + "-" + _date;
        Log.e("PickedDate: ", "Date: " + _pickedDate); //2019-02-12
    }
}, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.MONTH));
dialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
dialog.show();
Ketan Ramani
  • 4,874
  • 37
  • 42
4

Kotlin

Directly to the Date Picker:

datePicker.minDate = System.currentTimeMillis()

If you are using an object of DatePickerDialog:

datePickerDialog.datePicker.minDate = System.currentTimeMillis()
Ben
  • 3,346
  • 6
  • 32
  • 51
3

You can use this line into your code...

private Calendar cal;
private int day;
private int month;
private int year;

static final int DATE_PICKER_ID = 1111; 
TextView textView;

    textView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            cal = Calendar.getInstance();
            day = cal.get(Calendar.DAY_OF_MONTH);
            month = cal.get(Calendar.MONTH);
            year = cal.get(Calendar.YEAR);
            showDialog(DATE_PICKER_ID);

        }
    });

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case DATE_PICKER_ID:
            // create a new DatePickerDialog with values you want to show

            DatePickerDialog datePickerDialog = new DatePickerDialog(this, datePickerListener, year, month, day);
            Calendar calendar = Calendar.getInstance();

            calendar.add(Calendar.DATE, 0); // Add 0 days to Calendar
            Date newDate = calendar.getTime();
            datePickerDialog.getDatePicker().setMinDate(newDate.getTime()-(newDate.getTime()%(24*60*60*1000)));
            return datePickerDialog;
    }
    return null;
}

private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() {
    // the callback received when the user "sets" the Date in the
    // DatePickerDialog
    public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {

        textViewTime.setText(selectedDay + "/" + (selectedMonth + 1) + "/" + selectedYear);
    }
};
Sikander Bhutto
  • 226
  • 1
  • 11
  • And what for `calendar.add(Calendar.DATE, 0);` and a `Calendar calendar` itself if it is not used? Date newDate = new Date(); is enough. – CoolMind Nov 30 '16 at 08:34
3

You can use DatePicker#setMinDate() function to set a minimum date.

 datePickerDialog.getDatePicker().setMinDate(calendar.getTimeInMillis());
Karan Chunara
  • 518
  • 4
  • 15
2

Ok so I am using MaterialDatePicker Library and its too simple to set minimum date on it.

DatePickerDialog mDatePickerDialog = DatePickerDialog.newInstance(listener,
                mTime.year, mTime.month, mTime.monthDay);
mDatePickerDialog.setYearRange(2016, 2036);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis() - 1000);
mDatePickerDialog.setMinDate(c);
Pradeep Kumar Kushwaha
  • 2,231
  • 3
  • 23
  • 34
2

I had the same issue. Here is how i solved it.

Step 1: Declare click listener for opening the date picker.

dateTime.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         showDateTimePicker();
     }
 });

Step 2: Declare a listener which listens for Date change.

    public void showDateTimePicker(){
     final Calendar currentDate = Calendar.getInstance();
     date = Calendar.getInstance();
     DatePickerDialog.OnDateSetListener dateSetListener = new 
     DatePickerDialog.OnDateSetListener() {
     @Override
     public void onDateSet(DatePicker datePicker, int year, int 
     monthOfYear, int dayOfMonth) {
     date.set(year, monthOfYear, dayOfMonth);
    //use this date as per your requirement
     }
 };
}

Step 3: Now we need to declare a date picker dialog too inside the above showDateTimePicker() method. We will also be limiting the access to past dates in this step.

          public void showDateTimePicker(){
             final Calendar currentDate = Calendar.getInstance();
             date = Calendar.getInstance();

            DatePickerDialog.OnDateSetListener dateSetListener = new 
            DatePickerDialog.OnDateSetListener() {
             @Override
             public void onDateSet(DatePicker datePicker, int year, int 
             monthOfYear, int dayOfMonth) {
             date.set(year, monthOfYear, dayOfMonth);

            //use this date as per your requirement
             }
         };
          DatePickerDialog datePickerDialog = new  
          DatePickerDialog(**Your Activity Name.this**, dateSetListener, 
          currentDate.get(Calendar.YEAR), 
          currentDate.get(Calendar.MONTH),   
          currentDate.get(Calendar.DAY_OF_MONTH));
        // Limiting access to past dates in the step below:
 datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
         datePickerDialog.show();
        }

This is all that you need to do. Here is the final code that you may want to look:

    private Date date;

dateTime.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             showDateTimePicker();
         }
     });



public void showDateTimePicker(){
 final Calendar currentDate = Calendar.getInstance();
date = Calendar.getInstance();

 DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
     @Override
     public void onDateSet(DatePicker datePicker, int year, int monthOfYear, int dayOfMonth) {
         date.set(year, monthOfYear, dayOfMonth);

    //use this date as per your requirement
     }
 };
 DatePickerDialog datePickerDialog = new  DatePickerDialog(**Your Activity Name.this**, dateSetListener, currentDate.get(Calendar.YEAR), currentDate.get(Calendar.MONTH),   currentDate.get(Calendar.DAY_OF_MONTH));
 datePickerDialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
 datePickerDialog.show();
}

Hope it helps someone.

asm1609
  • 29
  • 5
1

This depends on what you want to disable if you want to set to minimum date to be up to a couple of days then the best approach is to use LocalDateTime like this:

        val ldt: LocalDateTime = LocalDateTime.now().minusDays(30)
        val zone: ZoneId = ZoneId.of("Europe/Berlin")

        val zoneOffSet: ZoneOffset = zone.rules.getOffset(ldt)
        dpd.datePicker.minDate = ldt.toInstant(zoneOffSet).toEpochMilli()
        dpd.datePicker.maxDate = System.currentTimeMillis()
        dpd.show()

You set the new local date-time to be up to minus 30 days from now and after that, you set in which time zone it needs to be for my example I am using "Europe/Berlin" time, you attach it to dpd.datePicker.minDate = ldt.toInstant(zoneOffSet).toEpochMilli() set to epochMilli and that's it

1

If this is your date picker (code from my own existing project)

   <DatePicker
                android:id="@+id/date"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="17dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="17dp"
                android:layout_marginBottom="31dp"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/outlinedTextField"
                android:datePickerMode="calendar"/>

Reference the DatePicker as follows :

 private DatePicker date;

Inside appropriate method initialize it depending on whether fragment or activity whatever

  date = view.findViewById(R.id.date);

Before you select the data or submit make sure you disable the past date (date before today or depending on your need ) like

     // disable date before today
    Calendar today = Calendar.getInstance();
    long now = today.getTimeInMillis();
    date.setMinDate(now);

Now all the past dates will be disabled meaning they will not be selectable. That should work.

Badri Paudel
  • 1,365
  • 18
  • 19
1

If you are using an object of `DatePickerDialog

datePicker.setMinDate(System.currentTimeMillis() - 1000);

This will disable past dates.

0

For me, to disable year, month, and the days, I used below code

datePickerDialog.minDate = Calendar.getInstance().apply {
            set(
                minYear,
                minMonth,
                minMonth,
                currentDate.hours,
                currentDate.minutes + 1
            )
        }
nasibeyyubov
  • 1,735
  • 3
  • 11
  • 28