Em Java, obtenha todas as datas dos finais de semana de um determinado mês
Pergunta
Preciso encontrar todas as datas de fim de semana de um determinado mês e de um determinado ano.
Por exemplo:Para 01(mês), 2010(ano), a saída deve ser:2,3,9,10,16,17,23,24,30,31, todas as datas de fim de semana.
Solução
Aqui está uma versão aproximada com comentários descrevendo as etapas:
// 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
Outras dicas
java.time
Você pode usar o Fluxo Java 8 e a pacote java.time.Aqui um IntStream
de 1
ao número de dias em um determinado mês é gerado.Este fluxo é mapeado para um fluxo de LocalDate
no mês determinado e então filtrado para manter os de sábado e domingo.
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() + " "));
}
}
Encontramos o mesmo resultado da primeira resposta (2 3 9 10 16 17 23 24 30 31).
O Resposta de Lokni parece estar correto, com pontos de bônus pelo uso de Streams.
EnumSet
Minha sugestão de melhoria: EnumSet
.Esta classe é uma implementação extremamente eficiente de Set
.Representados internamente como vetores de bits, eles são rápidos de executar e ocupam muito pouca memória.
Usando um EnumSet
permite que você código suave a definição do fim de semana passando por um Set<DayOfWeek>
.
Set<DayOfWeek> dows = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY );
Demonstração usando a sintaxe antiga sem Streams.Você poderia se adaptar Código da resposta de Lokni para usar um EnumSet
de maneira semelhante.
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
Você também pode fazer uso do TemporalAdjuster
interface que fornece classes que manipulam valores de data e hora.O TemporalAdjusters
classe (observe o plural s
) fornece várias implementações úteis.
O Três Dez-Extra projeto fornece classes trabalhando com java.time.Isto inclui um TemporalAdjuster
implementação, Temporals.nextWorkingDay()
.
Você pode escrever sua própria implementação para fazer o oposto, um nextWeekendDay
ajustador temporal.
Sobre java.time
O java.time framework é integrado ao Java 8 e posterior.Essas aulas substituem as velhas e problemáticas legado classes de data e hora, como java.util.Date
, Calendar
, & SimpleDateFormat
.
O Hora Joda projeto, agora em Modo de manutenção, aconselha a migração para o java.time Aulas.
Para saber mais, consulte o Tutorial Oráculo.E pesquise no Stack Overflow muitos exemplos e explicações.A especificação é JSR 310.
Você pode trocar java.time objetos diretamente com seu banco de dados.Use um Driver JDBC em conformidade com JDBC4.2 ou mais tarde.Não há necessidade de cordas, não há necessidade de java.sql.*
Aulas.
Onde obter as classes java.time?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, e posterior - Parte da API Java padrão com uma implementação agrupada.
- Java 9 adiciona alguns recursos e correções menores.
- Java SE 6 e Java SE 7
- A maioria dos java.time funcionalidade é portada para Java 6 e 7 em ThreeTen-Backport.
- Android
- Versões posteriores de implementações do pacote Android do java.time Aulas.
- Para Android anterior (<26), o TrêsTenABP projeto se adapta ThreeTen-Backport (Mencionado acima).Ver Como usar o ThreeTenABP….
O Três Dez-Extra projeto estende java.time com classes adicionais.Este projeto é um campo de provas para possíveis adições futuras ao java.time.Você pode encontrar algumas classes úteis aqui, como Interval
, YearWeek
, YearQuarter
, e mais.
Você poderia tentar assim:
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());
}
}