Obtenha o primeiro e o último dia do mês usando três, LocalDate


126

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/2014e 28/2/2014nos formatos LocalDate .

Usando três classes LocalDate.

Respostas:


179

Basta usar withDayOfMonthe lengthOfMonth():

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.withDayOfMonth(initial.lengthOfMonth());

3
Para sua informação, vejo outras respostas
— assylias

147

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.


5
Indo com este, usa os recursos da API feitos especificamente para lidar com este problema específico.
— jpangamarca

87

YearMonth

Para completude, e mais elegante na minha opinião, veja este uso de YearMonthclasse.

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

8
Melhor solução de todas.
— Agustí Sánchez

Informações extras: YearMonth yearMonth = YearMonth.parse ("202004", DateTimeFormatter.ofPattern ("aaaaMM"));
— egemen

quais são as vantagens disso em comparação com o LocalDate withmétodo?
— AndrewBloom

@AndrewBloom você não precisa usar uma função estática para obter o último dia do mês, e pelo menos no segundo exemplo, você não precisa ter um LocalDate instância para começar.
— herman

18

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

2
Caro downvoter, honestamente, não entendo o downvote porque minha resposta foi até um dia antes da de JodaStephen e apontou para a parte nova principalmente interessante, ou seja, o ajustador temporal para o final do mês. Isto é, não "copiei" a resposta de mais ninguém.
— Meno Hochschild

Ótima resposta! Esta solução é melhor porque é recomendada na documentação : "... encontrando o primeiro ou último dia do mês"
— peterchaula

4

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

Bom código, mas no Stack Overflow uma resposta deve abordar os detalhes da pergunta.
— Basil Bourque

Obrigado, eu concordo. Às vezes, encontramos código relacionado na discussão, pois também vim procurando por isso. Acabei de colocá-lo para esses usuários. Espero que esteja tudo bem. Obrigado.
— Anil Bhaskar

3
 LocalDate monthstart = LocalDate.of(year,month,1);
 LocalDate monthend = monthstart.plusDays(monthstart.lengthOfMonth()-1);

Descreva sua resposta
— smilyface

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

1
Parece um pouco complicado demais para mim. Também não dá o resultado correto. O último dia deste mês é 31/12/2019, mas seu snippet foi impresso em 30/12/2019.
— Ole VV

0

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


Não há necessidade de usar getLastDayOfMonth- veja minha resposta para uma abordagem mais simples.
— Jon Skeet

0

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

0

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.
— Basil Bourque

A pergunta pede um valor apenas de data, não os valores de data com hora que você procura aqui. E a terrível classe de legado Datenão tem nada a ver com a Questão e geralmente deve ser evitada.
— Basil Bourque

1
Para o fuso horário de La Paz, use o mais correto 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.
— Ole VV
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.