-
-
Save alexandreaquiles/10300153 to your computer and use it in GitHub Desktop.
import java.time.DayOfWeek; | |
import java.time.LocalDate; | |
import java.time.Month; | |
import java.time.YearMonth; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.function.Function; | |
import java.util.function.Predicate; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
public class DiasUteis { | |
public static Map<YearMonth, List<LocalDate>> doAno(int ano){ | |
return diasUteisDosMesesDoAno(mesesDoAno(ano)); | |
} | |
public static List<LocalDate> doMes(int ano, Month mes) { | |
return doMes(YearMonth.of(ano, mes)); | |
} | |
public static List<LocalDate> doMes(YearMonth mes) { | |
return diasUteisDosMesesDoAno(Stream.of(mes)).get(mes); | |
} | |
public static Map<YearMonth, List<LocalDate>> dosMeses(List<YearMonth> meses) { | |
return diasUteisDosMesesDoAno(meses.stream()); | |
} | |
private static Stream<YearMonth> mesesDoAno(int ano) { | |
return Stream.of(Month.values()).map(month -> YearMonth.of(ano, month)); | |
} | |
private static Map<YearMonth, List<LocalDate>> diasUteisDosMesesDoAno(Stream<YearMonth> mesesDoAno){ | |
return mesesDoAno | |
.collect(Collectors.toMap(Function.identity(), | |
ym -> todosOsDiasDoMesAno(ym) | |
.filter(diaUtil()) | |
.collect(Collectors.toList()))); | |
} | |
private static Predicate<LocalDate> diaUtil() { | |
return date -> !date.getDayOfWeek().equals(DayOfWeek.SATURDAY) && !date.getDayOfWeek().equals(DayOfWeek.SUNDAY); | |
} | |
private static Stream<LocalDate> todosOsDiasDoMesAno(YearMonth yearMonth) { | |
return Stream.iterate(yearMonth.atDay(1), date -> date.plusDays(1)).limit(yearMonth.lengthOfMonth()); | |
} | |
} |
import java.time.Month; | |
import java.time.YearMonth; | |
import java.util.Arrays; | |
import java.util.List; | |
public class ProgramaDiasUteis { | |
public static void main(String[] args) { | |
System.out.println(DiasUteis.doAno(2014)); | |
System.out.println(DiasUteis.doMes(2014, Month.APRIL)); | |
System.out.println(DiasUteis.doMes(YearMonth.of(2014, Month.APRIL))); | |
List<YearMonth> abrilEMaioDe2014 = Arrays.asList(YearMonth.of(2014, Month.APRIL), YearMonth.of(2014, Month.MAY)); | |
System.out.println(DiasUteis.dosMeses(abrilEMaioDe2014)); | |
} | |
} |
A ideia básica é gerar todos os dias válidos do mês-ano (YearMonth
), usando um Stream.iterate
limitado ao número de dias no mês (lengthOfMonth()
). Então, só são filtrados os que são dias úteis (no caso, de Segunda a Sexta). Depois, o resultado é coletado para uma lista.
Uma implementação mais completa deveria considerar feriados.
ficou BEM legal. da pra deixar clara a regra
ah, falta so ler de um arquivos os feriados :)
Mudei de
mesesDoAno.flatMap(todosOsDiasDoMesAno())
.filter(diaUtil())
.collect(Collectors.groupingBy(LocalDate::getMonth))
para
mesesDoAno
.collect(Collectors.toMap(Function.identity(),
ym -> todosOsDiasDoMesAno(ym)
.filter(diaUtil())
.collect(Collectors.toList())));
Na primeira versão, fazia um flatMap
que acabava juntando a lista dos LocalDate
de todos os meses.
Depois agrupava por LocalDate::getMonth
, o que gerava um mapa de Month
pra List<LocalDate>
, perdendo a informação do ano daquele mês.
Modifiquei para, dado um Stream<YearMonth>
, para todos os elementos criar um mapa do YearMonth
para a lista de LocalDate
. O gerador dos dias do mês, o método todosOsDiasDoMesAno
, agora recebe um YearMonth
como parâmetro.
Daria pra fazer um Map<YearMonth, List<LocalDate>>
na primeira versão com:
mesesDoAno.flatMap(todosOsDiasDoMesAno())
.filter(diaUtil())
.collect(Collectors.groupingBy(date -> YearMonth.of(date.getYear(), date.getMonth())));
Não sei qual jeito é mais legível... O mais rápido entre os dois parece ser o collect toMap. Mas, na verdade, o iterativo é mais rápido.
Dá pra fazer:
groupingBy(YearMonth::from);
ola gente que maravilha de código... alguém poderia me ajudar numa duvida....
Como eu poderia por exemplo dividir um valor de X em 3 semanas usando a nova api de datas..
tenho um sistema de vendas em que o vendedor vende um valor X divide pro cliente dele em 3 ou 4 ou 6 semanas....
Acho interessante a chamada
O método
diaUtil
retorna um lambda. Os parâmetros são passados na invocação (no caso, lá dentro dofilter
doStream
).