Ich habe Probleme mit der Berechnung, wann am nächsten letzten Tag des Monats eine Benachrichtigung gesendet werden soll.
Hier ist mein Code:
RecurrenceFrequency recurrenceFrequency = notification.getRecurrenceFrequency();
Calendar nextNotifTime = Calendar.getInstance();
Dies ist die Linie, die meiner Meinung nach Probleme verursacht:
nextNotifTime.add(recurrenceFrequency.getRecurrencePeriod(),
recurrenceFrequency.getRecurrenceOffset());
Wie kann ich den Kalender verwenden, um den letzten Tag des nächsten Monats für die Benachrichtigung richtig einzustellen?
Antworten:
Dies gibt das tatsächliche Maximum für den aktuellen Monat zurück. Zum Beispiel ist jetzt Februar des Schaltjahres, also gibt es 29 als zurück
int
.quelle
ActualMaximum
für jedes Datum zu bekommen . Rollen Sie die Kalenderinstanz einfach auf das gewünschte Datum, bevor Sie anrufengetActualMaximum
. Der erste Termin kann vongetActualMinimum()
nextNotification.setReadyDateTime(nextNotifTime.getTime());
ich dies stattdessen nicht tun :nextNotifTime.roll(Calendar.MONTH, true); nextNotifTime.getActualMaximum(Calendar.DAY_OF_MONTH); nextNotifTime.setTime(Calendar.DAY_OF_MONTH);
?java.time.temporal.TemporalAdjusters.lastDayOfMonth ()
Mit der
java.time
in Java 8 integrierten Bibliothek können Sie dieTemporalAdjuster
Schnittstelle verwenden. In derTemporalAdjusters
Utility-Klasse finden wir eine gebrauchsfertige Implementierung :lastDayOfMonth
.Wenn Sie Zeitinformationen hinzufügen müssen, können Sie alle für
LocalDate
dieLocalDateTime
Konvertierung verfügbaren wie verwendenquelle
LocalDateTime
. Dieser Klasse fehlt jegliches Konzept der Zeitzone oder des Versatzes von UTC. Es kann also nicht festgestellt werden, wann ein bestimmter Tag an einem bestimmten Ort tatsächlich beginnt. Diese Klasse funktioniert nur für einfache generische 24-Stunden-Tage, nicht für reale Tage. Geben Sie für reale Tage eine Zeitzone an :ZonedDateTime zdt = now.atStartOfDay( ZoneId.of( "Asia/Tokyo" ) ) ;
. Einige Tage an einigen Orten können aufgrund von Anomalien wie der Sommerzeit (DST) zu einer anderen Zeit beginnen, z. B. 01:00 Uhr.Und um den letzten Tag als Datumsobjekt zu erhalten:
quelle
Sie können den Kalender auf den ersten des nächsten Monats einstellen und dann einen Tag abziehen.
Nach dem Ausführen dieses Codes wird nextNotifTime auf den letzten Tag des aktuellen Monats gesetzt. Wenn heute der letzte Tag des Monats ist, bewirkt dieser Code, dass das Kalenderobjekt unverändert bleibt.
quelle
Folgendes führt immer zu korrekten Ergebnissen:
quelle
Die Verwendung der neuesten
java.time
Bibliothek ist hier die beste Lösung:Alternativ können Sie Folgendes tun:
quelle
Sie können auch YearMonth verwenden.
Mögen:
Siehe https://docs.oracle.com/javase/8/docs/api/java/time/YearMonth.html#atEndOfMonth--
quelle
Schaue auf die
getActualMaximum(int field)
Methode des Kalenderobjekts an.Wenn Sie Ihr Kalenderobjekt auf den Monat einstellen, für den Sie das letzte Datum suchen
getActualMaximum(Calendar.DAY_OF_MONTH)
, erhalten Sie den letzten Tag.quelle
quelle
Implementierung der Kotlin-Datumserweiterung mit
java.util.Calendar
Sie können die
toEndOfMonth
Funktion für jedes Datumsobjekt wie aufrufenDate().toEndOfMonth()
quelle