На Java, получить все даты выходных в данном месяце - PullRequest
12 голосов
/ 17 июля 2010

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

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

Ответы [ 4 ]

19 голосов
/ 17 июля 2010

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

// 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
11 голосов
/ 15 июня 2015

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).

2 голосов
/ 07 октября 2016

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

EnumSet

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

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

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

Демонстрация с использованием старомодного синтаксиса без потоков. Вы можете адаптировать код ответа Локни для использования 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 и more .

1 голос
/ 07 октября 2016

Вы можете попробовать вот так:

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());
      }
}
...