В Java, получить все выходные дни в данном месяце

Мне нужно найти все выходные для данного месяца и определенного года.

Например: на 01 (месяц), 2010 (год), выход должен быть: 2,3,9,10,16,17,23,24,30,31, все выходные.

Ответ 1

Вот грубая версия с комментариями, описывающими шаги:

// create a Calendar for the 1st of the required month
int year = 2010;
int month = Calendar.JANUARY;
Calendar cal = new GregorianCalendar(year, month, 1);
do {
    // get the day of the week for the current day
    int day = cal.get(Calendar.DAY_OF_WEEK);
    // check if it is a Saturday or Sunday
    if (day == Calendar.SATURDAY || day == Calendar.SUNDAY) {
        // print the day - but you could add them to a list or whatever
        System.out.println(cal.get(Calendar.DAY_OF_MONTH));
    }
    // advance to the next day
    cal.add(Calendar.DAY_OF_YEAR, 1);
}  while (cal.get(Calendar.MONTH) == month);
// stop when we reach the start of the next month

Ответ 2

java.time

Вы можете использовать поток Java 8 и пакет java.time. Здесь генерируется IntStream от 1 до количества дней в данном месяце. Этот поток сопоставляется с потоком LocalDate в данном месяце, а затем фильтруется для сохранения субботы и воскресенья.

import java.time.DayOfWeek;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.YearMonth;
import java.util.stream.IntStream;

class Stackoverflow{
    public static void main(String args[]){

        int year    = 2010;
        Month month = Month.JANUARY;

        IntStream.rangeClosed(1,YearMonth.of(year, month).lengthOfMonth())
                 .mapToObj(day -> LocalDate.of(year, month, day))
                 .filter(date -> date.getDayOfWeek() == DayOfWeek.SATURDAY ||
                                 date.getDayOfWeek() == DayOfWeek.SUNDAY)
                 .forEach(date -> System.out.print(date.getDayOfMonth() + " "));
    }
}

Мы находим тот же результат, что и первый ответ (2 3 9 10 16 17 23 24 30 31).

Ответ 3

Ответ от Локни, кажется, правильный, с бонусными баллами за использование потоков.

EnumSet

Мое предложение по улучшению: EnumSet. Этот класс является чрезвычайно эффективной реализацией Set. Представленные внутри как битовые векторы, они быстро выполняются и занимают очень мало памяти.

Использование EnumSet позволяет программно кодировать определение выходных, передавая Set<DayOfWeek>.

Set<DayOfWeek> dows = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY );

Демонстрация с использованием старомодного синтаксиса без потоков. Вы можете адаптировать код ответов Loknis для использования EnumSet аналогичным образом.

YearMonth ym = YearMonth.of( 2016 , Month.JANUARY ) ;
int initialCapacity = ( ( ym.lengthOfMonth() / 7 ) + 1 ) * dows.size() ;  // Maximum possible weeks * number of days per week.
List<LocalDate> dates = new ArrayList<>(  initialCapacity  );
for (int dayOfMonth = 1;  dayOfMonth <= ym.lengthOfMonth() ;  dayOfMonth ++) {
    LocalDate ld =  ym.atDay( dayOfMonth ) ;
    DayOfWeek dow = ld.getDayOfWeek() ;
    if( dows.contains( dow ) ) {  
        // Is this date *is* one of the days we care about, collect it.
        dates.add( ld );
    }
}

TemporalAdjuster

Вы также можете использовать интерфейс TemporalAdjuster который предоставляет классы, которые манипулируют значениями даты и времени. TemporalAdjusters класс (обратите внимание на множественное число s) обеспечивает несколько удобных реализаций.

Проект ThreeTen-Extra предоставляет классы, работающие с java.time. Это включает в себя TemporalAdjuster реализацию, Temporals.nextWorkingDay().

Вы можете написать свою собственную реализацию, чтобы сделать наоборот, временный регулятор nextWeekendDay.


О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытеснять неприятные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, и SimpleDateFormat.

Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.

Чтобы узнать больше, смотрите Oracle Tutorial. И поиск для многих примеров и объяснений. Спецификация JSR 310.

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*.

Где взять классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и другие.

Ответ 4

Вы можете попробовать следующее:

int year=2016;
int month=10;
calendar.set(year, 10- 1, 1);
int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
ArrayList<Date> sundays = new ArrayList<Date>();>

for (int d = 1;  d <= daysInMonth;  d++) {
      calendar.set(Calendar.DAY_OF_MONTH, d);
      int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
      if (dayOfWeek==Calendar.SUNDAY) {
            calendar.add(Calendar.DATE, d);
            sundays.add(calendar.getTime());
      }
}