Мне нужно найти все выходные для данного месяца и определенного года.
Например: на 01 (месяц), 2010 (год), выход должен быть: 2,3,9,10,16,17,23,24,30,31, все выходные.
Мне нужно найти все выходные для данного месяца и определенного года.
Например: на 01 (месяц), 2010 (год), выход должен быть: 2,3,9,10,16,17,23,24,30,31, все выходные.
Вот грубая версия с комментариями, описывающими шаги:
// 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
Вы можете использовать поток 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).
Ответ от Локни, кажется, правильный, с бонусными баллами за использование потоков.
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 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
и другие.
Вы можете попробовать следующее:
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());
}
}