Ottieni il primo e l'ultimo giorno del mese utilizzando tre, LocalDate


127

Ho un LocalDate che deve ottenere il primo e l'ultimo giorno del mese. Come lo faccio?

per esempio. 13/2/2014 Ho bisogno di ottenere 1/2/2014e 28/2/2014nei formati LocalDate .

Utilizzo di tre classi LocalDate.

Risposte:


180

Basta usare withDayOfMonthe lengthOfMonth():

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

3
Per tua informazione, vedo altre risposte
assylias

147

L'API è stata progettata per supportare una soluzione che corrisponda strettamente ai requisiti aziendali

import static java.time.temporal.TemporalAdjusters.*;

LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.with(firstDayOfMonth());
LocalDate end = initial.with(lastDayOfMonth());

Tuttavia, anche le soluzioni di Jon vanno bene.


5
Andando con questo, utilizza le risorse API appositamente realizzate per gestire questo particolare problema.
jpangamarca

87

YearMonth

Per completezza, e secondo me più elegante, vedi questo uso della YearMonthclasse.

YearMonth month = YearMonth.from(date);
LocalDate start = month.atDay(1);
LocalDate end   = month.atEndOfMonth();

Per il primo e l'ultimo giorno del mese corrente, questo diventa:

LocalDate start = YearMonth.now().atDay(1);
LocalDate end   = YearMonth.now().atEndOfMonth();

8
La migliore soluzione in assoluto.
Agustí Sánchez

Informazioni aggiuntive: YearMonth yearMonth = YearMonth.parse ("202004", DateTimeFormatter.ofPattern ("yyyyMM"));
egemen

quali sono i vantaggi rispetto al LocalDate withmetodo?
AndrewBloom

@AndrewBloom non è necessario utilizzare una funzione statica per ottenere l'ultimo giorno del mese e, almeno nel secondo esempio, non è necessario disporre di LocalDateun'istanza con cui iniziare.
Herman

18

La risposta di Jon Skeets è giusta e ha meritato il mio voto positivo, aggiungendo solo questa soluzione leggermente diversa per completezza:

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, onestamente, non capisco il downvote perché la mia risposta era anche un giorno prima di quella di JodaStephen e indicava la parte nuova principalmente interessante, ovvero il regolatore temporale per la fine del mese. Cioè non ho "copiato" la risposta da nessun altro.
Meno Hochschild,

Bella risposta! Questa soluzione è migliore perché è consigliata nei documenti : "... trovare il primo o l'ultimo giorno del mese"
peterchaula

4

Se qualcuno viene a cercare il primo giorno del mese precedente e l' ultimo giorno del mese precedente :

public static LocalDate firstDayOfPreviousMonth(LocalDate date) {
        return date.minusMonths(1).withDayOfMonth(1);
    }


public static LocalDate lastDayOfPreviousMonth(LocalDate date) {
        return date.withDayOfMonth(1).minusDays(1);
    }

Buon codice, ma in Stack Overflow una risposta dovrebbe affrontare le specifiche della domanda.
Basil Bourque

Grazie, sono d'accordo. A volte troviamo codice correlato nel thread, poiché anch'io cercavo questo. L'ho messo solo per tali utenti. Spero che vada bene. Grazie.
Anil Bhaskar

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

Per favore descrivi la tua risposta
smilyface

1

Puoi provare questo per evitare di indicare una data personalizzata e se è necessario visualizzare le date di inizio e fine del mese corrente:

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

Risultato:

>     Start of month: 2019-12-01
>     End of month: 2019-12-30

1
Mi sembra un po 'troppo complicato. Inoltre non dà il risultato corretto. L'ultimo giorno di questo mese è il 31/12/2019, ma il tuo frammento è stato stampato il 30/12/2019.
Ole VV

0

Prova questo:

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

puoi trovare l'output desiderato ma devi occuparti del parametro true / false per il metodo getLastDayOfMonth

quel parametro denota anno bisestile


Non è necessario utilizzare getLastDayOfMonth: vedere la mia risposta per un approccio più semplice.
Jon Skeet

0

se vuoi farlo solo con la 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

Solo qui per mostrare la mia implementazione per la soluzione @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è esattamente la classe sbagliata da usare qui. Stai scartando preziose informazioni sulla zona / offset.
Basil Bourque,

La domanda richiede un valore di sola data, non i valori di data con ora che cerchi qui. E la terribile classe ereditaria Datenon ha nulla a che fare con la Domanda e dovrebbe essere generalmente evitata.
Basil Bourque,

1
Per il fuso orario di La Paz si prega di utilizzare il più corretto ZoneId.of("America/La_Paz"). Per le date odierne darà lo stesso risultato, ma forse non per date storiche o date in un futuro ulteriore.
Ole VV
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.