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.

user1746050
quelle

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());
Jon Skeet
quelle
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.

JodaStephen
quelle
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();
ihr Mann
quelle
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());
Meno Hochschild
quelle
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);
    }
Anil Bhaskar
quelle
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);
dersu
quelle
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
VSs
quelle
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

Shekhar Rajput
quelle
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);
MrSmith42
quelle
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();
}
Luis Roberto
quelle
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