22

I'm using the datePicker and I can disable last days of today and later days after 30 days by the following code:

DatePickerDialog datePicker = new DatePickerDialog();

             Calendar calender = Calendar.getInstance();
             long today = calender.getTimeInMillis();
             final long oneDay = 24 * 60 * 60 * 1000L;

             Date previousDays = new Date(today - 1000);
             datePicker.setMinDate(DateToCalendar(previousDays));

             Date nextMonth = new Date(today + 30 * oneDay);
             datePicker.setMaxDate(DateToCalendar(nextMonth));

If I want to disable Friday of every month, how can I do this?

Emy Alsabbagh
  • 287
  • 1
  • 3
  • 8

7 Answers7

12

You can use this library Material Date Time Picker, here you can set an option to show specific dates, For Example:

datePicker.setSelectableDays(Calendar[] days)

And pass array of Calendar as an parameter which contains all the selectable date.

himanshu1496
  • 1,921
  • 19
  • 34
10

Use custom DatePickerDialog

add this in build.gradle

compile 'com.wdullaer:materialdatetimepicker:3.5.1'

implement

DatePickerDialog.OnDateSetListener to your class

and import

import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; instead of 'import android.app.DatePickerDialog;'

and add this method

 private void showDatePicker() { 

    Calendar calendar = Calendar.getInstance();

    DatePickerDialog dpd = DatePickerDialog.newInstance(
            this,
            calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH)
    );
    dpd.show(getActivity().getFragmentManager(), "DatePickerDialog");

    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    String a = "07-03-2018"; // example

    java.util.Date date = null;

    try {
        date = sdf.parse(a);
    } catch (ParseException e) {
        e.printStackTrace();
    }

    calendar = dateToCalendar(date);
    System.out.println(calendar.getTime());

    List<Calendar> dates = new ArrayList<>();
    dates.add(calendar);
    Calendar[] disabledDays1 = dates.toArray(new Calendar[dates.size()]);
    dpd.setDisabledDays(disabledDays1);

}

    private Calendar dateToCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }




@Override
public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) {

    String date = dayOfMonth+"/"+(monthOfYear+1)+"/"+year;
    textview.setText(date);

}

call showDatePicker().

for multiple days

Change this

     String[] holidays = {"07-03-2018","05-03-2018","10-03-2018"};

    java.util.Date date = null;

    for (int i = 0;i < holidays.length; i++) {

        try {
            date = sdf.parse(holidays[i]);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        calendar = dateToCalendar(date);
        System.out.println(calendar.getTime());

        List<Calendar> dates = new ArrayList<>();
        dates.add(calendar);
        Calendar[] disabledDays1 = dates.toArray(new Calendar[dates.size()]);
        dpd.setDisabledDays(disabledDays1);
    }
akash bs
  • 258
  • 6
  • 15
  • Change from "dpd.show(getActivity().getFragmentManager(), "DatePickerDialog");" to "dpd.show(getSupportFragmentManager(), "DatePickerDialog");" if you are using androidx and also as FragmentManager is deprecated. – Sriram Nadiminti Jun 21 '22 at 09:06
6

As the accepted answers here rely on the custom implementation of com.wdullaer, I would like to propose another solution that I have just implemente using the standard MaterialDatePicker and a custom DateValidator:

            // Create a custom date validator to only enable dates that are in the list
        val customDateValidator = object: CalendarConstraints.DateValidator {
            override fun describeContents(): Int {  return 0  }
            override fun writeToParcel(dest: Parcel?, flags: Int) {    }
            override fun isValid(date: Long): Boolean {

                listOfPossibleDatesAsLong.forEach {
                    val itemDateTime = Calendar.getInstance()
                    itemDateTime.timeInMillis = it

                    val dateDateTime = Calendar.getInstance()
                    dateDateTime.timeInMillis = date

                    if(itemDateTime.get(Calendar.YEAR) == dateDateTime.get(Calendar.YEAR)
                        && itemDateTime.get(Calendar.MONTH) == dateDateTime.get(Calendar.MONTH)
                        && itemDateTime.get(Calendar.DAY_OF_MONTH) == dateDateTime.get(Calendar.DAY_OF_MONTH))
                        return true
                }
                return false
            }
        }

Additionally to other constraints in the CalendarConstraints, just set the customDateValidator now, this can also be used together with setStart(...) and setEnd(...)

        // Build constraints.
        val constraintsBuilder =
            CalendarConstraints.Builder().apply {
                    // other constraints
                    setValidator(customDateValidator)
                }
            }

Then define the datePicker and show it

        val datePicker =
            MaterialDatePicker.Builder.datePicker()
                .setTitleText("Select date")
                .setSelection(MaterialDatePicker.todayInUtcMilliseconds())
                .setCalendarConstraints(constraintsBuilder.build())
                .build()

        datePicker.addOnPositiveButtonClickListener {
            // Respond to positive button click...
        }

        datePicker.show(parentFragmentManager, "tag")

I need to admit that I haven't understood if describeContents and writeToParcel not being implemented properly would have a negative impact on anything, maybe this could be discussed here. However, for my purposes this works perfectly.

Patrick Lang
  • 501
  • 6
  • 9
  • The way how I compared the dates in the validator did not work on real devices, so I updated the code above. – Patrick Lang Jun 27 '21 at 10:08
  • You are using kotlin and can avoid that inefficient foreach. Your 'override fun isValid' could be yourList.any { DateUtils.isSameDay(it.time, Date(date)) } – Yago Rey Aug 25 '22 at 18:49
4

That is not possible with the android datepicker and you need to create a custom picker for yourself. See MaterialDateTimePicker

To disable Sundays you have to pass the array like this

      GregorianCalendar g1=new GregorianCalendar();
      g1.add(Calendar.DATE, 1);
      GregorianCalendar gc = new GregorianCalendar();
      gc.add(Calendar.DAY_OF_MONTH, 30);
       List<Calendar> dayslist= new LinkedList<Calendar>();
Calendar[] daysArray;
Calendar cAux = Calendar.getInstance();
while ( cAux.getTimeInMillis() <= gc.getTimeInMillis()) {
    if (cAux.get(Calendar.DAY_OF_WEEK) != 1) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(cAux.getTimeInMillis());
        dayslist.add(c);
    }
    cAux.setTimeInMillis(cAux.getTimeInMillis() + (24*60*60*1000));
}
daysArray = new Calendar[dayslist.size()];
for (int i = 0; i<daysArray.length;i++)
{
    daysArray[i]=dayslist.get(i);
}
datePickerDialog.setSelectableDays(daysArray);
aenugula karthik
  • 339
  • 5
  • 19
3

Visit https://stackoverflow.com/a/44692231/6631959 Best method and easy to understand... if u are searching for how to disable a specified date it is better. not a looping procedure. giving any exact date and disabling it.

The code is HEre::

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
                    String a = "26-07-2017";
                    java.util.Date date = null;
                    try {
                        date = sdf.parse(a);
                        MainActivity obj = new MainActivity();
                        calendar = obj.dateToCalendar(date);
                        System.out.println(calendar.getTime());
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    List<Calendar> dates = new ArrayList<>();
                    dates.add(calendar);
                    Calendar[] disabledDays1 = dates.toArray(new Calendar[dates.size()]);
                    dpd.setDisabledDays(disabledDays1);
    private Calendar dateToCalendar(Date date) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            return calendar;
        }
Bharath
  • 277
  • 4
  • 10
1

Try Android Material Date and Timepicker

Source Link

Disabled Sundays and Saturdays.

enter image description here

You can also disable any specific date using setDisabledDays() method

            //Disable all SUNDAYS and SATURDAYS between Min and Max Dates
            for (Calendar loopdate = min_date_c; min_date_c.before(max_date_c); min_date_c.add(Calendar.DATE, 1), loopdate = min_date_c) {
                int dayOfWeek = loopdate.get(Calendar.DAY_OF_WEEK);
                if (dayOfWeek == Calendar.SUNDAY || dayOfWeek == Calendar.SATURDAY) {
                    Calendar[] disabledDays =  new Calendar[1];
                    disabledDays[0] = loopdate;
                    datePickerDialog.setDisabledDays(disabledDays);
                }
            }
Code Spy
  • 9,626
  • 4
  • 66
  • 46
1

Use MaterialDatePicker of https://github.com/material-components/material-components-android

Example disable weekends in picker

val constraintsBuilder =
        CalendarConstraints.Builder().setValidator(DateValidatorWeekdays()).build()

    MaterialDatePicker.Builder.datePicker().setCalendarConstraints(constraintsBuilder).build()
        .show(childFragmentManager, "Data_Picker")

DateValidator class:

https://github.com/material-components/material-components-android/blob/master/catalog/java/io/material/catalog/datepicker/DateValidatorWeekdays.java

Thang Duong
  • 550
  • 4
  • 6