Holen Sie sich den ersten und letzten Tag des Monats mit threeten, LocalDate


125

Ich habe ein lokales Datum, das den ersten und letzten Tag des Monats abrufen muss. Wie mache ich das?

z.B. 13/2/2014 Ich muss 1/2/2014und 28/2/2014in LocalDate- Formaten.

Verwenden der threeten LocalDate-Klasse.

Antworten:


178

Verwenden Sie einfach withDayOfMonthund lengthOfMonth():

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

3
FYI sehen andere Antworten
Assylias

147

Die API wurde entwickelt, um eine Lösung zu unterstützen, die den Geschäftsanforderungen genau entspricht

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

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

Jons Lösungen sind jedoch auch in Ordnung.


5
In diesem Fall werden die API-Ressourcen verwendet, die speziell für dieses spezielle Problem entwickelt wurden.
Jpangamarca

87

YearMonth

Der Vollständigkeit halber und meiner Meinung nach eleganter, siehe diese Verwendung der YearMonthKlasse.

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

Für den ersten und letzten Tag des aktuellen Monats lautet dies:

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

8
Beste Lösung von allen.
Agustí Sánchez

Zusätzliche Informationen: YearMonth yearMonth = YearMonth.parse ("202004", DateTimeFormatter.ofPattern ("yyyyMM"));
Egemen

Was sind die Vorteile gegenüber der LocalDate withMethode?
AndrewBloom

@AndrewBloom Sie müssen keine statische Funktion verwenden, um den letzten Tag des Monats abzurufen, und zumindest im zweiten Beispiel benötigen Sie zunächst keine LocalDateInstanz.
Hermann

18

Die Antwort von Jon Skeets ist richtig und hat meine Zustimmung verdient, der Vollständigkeit halber nur diese etwas andere Lösung hinzugefügt:

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
Lieber Downvoter, ehrlich gesagt, ich verstehe die Downvote nicht, weil meine Antwort sogar einen Tag vor der von JodaStephen war und auf den hauptsächlich interessanten neuen Teil hinwies, nämlich den zeitlichen Einsteller für das Monatsende. Das heißt, ich habe die Antwort von niemand anderem "kopiert".
Meno Hochschild

Gute Antwort! Diese Lösung ist besser, weil in den Dokumenten empfohlen wird : "... den ersten oder letzten Tag des Monats finden"
peterchaula

4

Wenn jemand nach dem ersten Tag des Vormonats und dem letzten Tag des Vormonats sucht :

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


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

Guter Code, aber im Stapelüberlauf sollte eine Antwort die Besonderheiten der Frage berücksichtigen.
Basil Bourque

Danke, ich stimme zu. Manchmal finden wir verwandten Code im Thread, da ich auch danach gesucht habe. Ich habe es nur für solche Benutzer gestellt. Hoffe das ist okay Vielen Dank.
Anil Bhaskar

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

Bitte beschreiben Sie Ihre Antwort
smilyface

1

Sie können dies versuchen, um zu vermeiden, dass ein benutzerdefiniertes Datum angegeben wird und Start- und Enddaten des aktuellen Monats angezeigt werden müssen:

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

Ergebnis:

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

1
Es scheint mir ein bisschen zu kompliziert. Es gibt auch nicht das richtige Ergebnis. Der letzte Tag dieses Monats ist der 31.12.2019, aber Ihr Snippet wurde am 30.12.2019 gedruckt.
Ole VV

0

Versuche dies:

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

Sie können die gewünschte Ausgabe finden, müssen sich jedoch um den Parameter true / false für die Methode getLastDayOfMonth kümmern

Dieser Parameter bezeichnet das Schaltjahr


Es besteht keine Notwendigkeit zu verwenden getLastDayOfMonth- siehe meine Antwort für einen einfacheren Ansatz.
Jon Skeet

0

Wenn Sie dies nur mit der LocalDate-Klasse tun möchten:

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

Nur hier, um meine Implementierung für die @ herman-Lösung zu zeigen

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

LocalDateTimeist genau die falsche Klasse, die hier verwendet wird. Sie verwerfen wertvolle Zonen- / Versatzinformationen.
Basil Bourque

In der Frage wird nach einem Nur-Datum-Wert gefragt, nicht nach den Datums- / Zeitwerten, die Sie hier suchen. Und die schreckliche Legacy-Klasse Datehat nichts mit der Frage zu tun und sollte generell vermieden werden.
Basil Bourque

1
Für die Zeitzone La Paz verwenden Sie bitte die korrektere ZoneId.of("America/La_Paz"). Für heutige Daten wird es das gleiche Ergebnis geben, aber möglicherweise nicht für historische Daten oder Daten in einer weiteren Zukunft.
Ole VV
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.