Eu tenho um LocalDate que precisa ser o primeiro e o último dia do mês. Como faço isso?
por exemplo. 13/2/2014
Eu preciso obter 1/2/2014
e 28/2/2014
nos formatos LocalDate .
Usando três classes LocalDate.
Eu tenho um LocalDate que precisa ser o primeiro e o último dia do mês. Como faço isso?
por exemplo. 13/2/2014
Eu preciso obter 1/2/2014
e 28/2/2014
nos formatos LocalDate .
Usando três classes LocalDate.
Respostas:
A API foi projetada para oferecer suporte a uma solução que corresponda intimamente aos requisitos de negócios
import static java.time.temporal.TemporalAdjusters.*;
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.with(firstDayOfMonth());
LocalDate end = initial.with(lastDayOfMonth());
No entanto, as soluções de Jon também são boas.
YearMonth
Para completude, e mais elegante na minha opinião, veja este uso de YearMonth
classe.
YearMonth month = YearMonth.from(date);
LocalDate start = month.atDay(1);
LocalDate end = month.atEndOfMonth();
Para o primeiro e último dia do mês atual, isso se torna:
LocalDate start = YearMonth.now().atDay(1);
LocalDate end = YearMonth.now().atEndOfMonth();
LocalDate
with
método?
LocalDate
instância para começar.
A resposta de Jon Skeets está certa e mereceu meu voto positivo, apenas adicionando esta solução ligeiramente diferente para completude:
import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.with(lastDayOfMonth());
Se alguém vier procurar o primeiro dia do mês anterior e o último dia do mês anterior :
public static LocalDate firstDayOfPreviousMonth(LocalDate date) {
return date.minusMonths(1).withDayOfMonth(1);
}
public static LocalDate lastDayOfPreviousMonth(LocalDate date) {
return date.withDayOfMonth(1).minusDays(1);
}
Você pode tentar fazer isso para evitar a indicação de data personalizada e se houver necessidade de exibir as datas de início e término do mês atual:
LocalDate start = LocalDate.now().minusDays(LocalDate.now().getDayOfMonth()-1);
LocalDate end = LocalDate.now().minusDays(LocalDate.now().getDayOfMonth()).plusMonths(1);
System.out.println("Start of month: " + start);
System.out.println("End of month: " + end);
Resultado:
> Start of month: 2019-12-01
> End of month: 2019-12-30
Experimente isto:
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.getMonthOfYear().getLastDayOfMonth(false));
System.out.println(start);
System.out.println(end);
você pode encontrar a saída desejada, mas precisa cuidar do parâmetro true / false para getLastDayOfMonth método
esse parâmetro denota ano bissexto
getLastDayOfMonth
- veja minha resposta para uma abordagem mais simples.
se você quiser fazer isso apenas com a classe LocalDate:
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = LocalDate.of(initial.getYear(), initial.getMonthValue(),1);
// Idea: the last day is the same as the first day of next month minus one day.
LocalDate end = LocalDate.of(initial.getYear(), initial.getMonthValue(), 1).plusMonths(1).minusDays(1);
Só aqui para mostrar minha implementação para a solução @herman
ZoneId americaLaPazZone = ZoneId.of("UTC-04:00");
static Date firstDateOfMonth(Date date) {
LocalDate localDate = convertToLocalDateWithTimezone(date);
YearMonth baseMonth = YearMonth.from(localDate);
LocalDateTime initialDate = baseMonth.atDay(firstDayOfMonth).atStartOfDay();
return Date.from(initialDate.atZone(americaLaPazZone).toInstant());
}
static Date lastDateOfMonth(Date date) {
LocalDate localDate = convertToLocalDateWithTimezone(date);
YearMonth baseMonth = YearMonth.from(localDate);
LocalDateTime lastDate = baseMonth.atEndOfMonth().atTime(23, 59, 59);
return Date.from(lastDate.atZone(americaLaPazZone).toInstant());
}
static LocalDate convertToLocalDateWithTimezone(Date date) {
return LocalDateTime.from(date.toInstant().atZone(americaLaPazZone)).toLocalDate();
}
LocalDateTime
é exatamente a classe errada para usar aqui. Você está descartando informações valiosas de zona / deslocamento.
Date
não tem nada a ver com a Questão e geralmente deve ser evitada.
ZoneId.of("America/La_Paz")
. Para as datas atuais, ele dará o mesmo resultado, mas talvez não para datas históricas ou datas em um futuro futuro.