Mam problemy z obliczeniem, kiedy następny ostatni dzień miesiąca przypada na powiadomienie, które ma zostać wysłane.
Oto mój kod:
RecurrenceFrequency recurrenceFrequency = notification.getRecurrenceFrequency();
Calendar nextNotifTime = Calendar.getInstance();
To jest linia powodująca problemy, które moim zdaniem:
nextNotifTime.add(recurrenceFrequency.getRecurrencePeriod(),
recurrenceFrequency.getRecurrenceOffset());
Jak mogę użyć Kalendarza, aby poprawnie ustawić ostatni dzień następnego miesiąca dla powiadomienia?
Odpowiedzi:
Zwraca rzeczywiste maksimum dla bieżącego miesiąca. Na przykład teraz jest luty roku przestępnego, więc zwraca 29 jako
int
.źródło
ActualMaximum
na każdą randkę. Po prostu przenieś instancję kalendarza do wymaganej daty przed zadzwonieniemgetActualMaximum
. Pierwszą datę można uzyskać przezgetActualMinimum()
nextNotification.setReadyDateTime(nextNotifTime.getTime());
w związku z tym nie powinien to zrobić w zamian:nextNotifTime.roll(Calendar.MONTH, true); nextNotifTime.getActualMaximum(Calendar.DAY_OF_MONTH); nextNotifTime.setTime(Calendar.DAY_OF_MONTH);
?java.time.temporal.TemporalAdjusters.lastDayOfMonth ()
Korzystając z
java.time
biblioteki wbudowanej w Javę 8, możesz korzystać zTemporalAdjuster
interfejsu. Znaleźć implementacja gotowy do użycia wTemporalAdjusters
klasie użytkowej:lastDayOfMonth
.Jeśli chcesz dodać informacje o czasie, możesz użyć dowolnego dostępnego
LocalDate
doLocalDateTime
konwersji, takiego jakźródło
LocalDateTime
. W tej klasie brakuje jakiejkolwiek koncepcji strefy czasowej lub przesunięcia względem czasu UTC. Nie może więc określić, kiedy konkretny dzień w określonym miejscu faktycznie się zaczyna. Ta klasa działa tylko w zwykłych ogólnych 24-godzinnych dniach, a nie w rzeczywistych dniach. Dla prawdziwych dni, należy określić strefę czasową:ZonedDateTime zdt = now.atStartOfDay( ZoneId.of( "Asia/Tokyo" ) ) ;
. Niektóre dni w niektórych miejscach mogą rozpoczynać się o innej godzinie, na przykład o godzinie 01:00, z powodu anomalii, takich jak czas letni (DST).Aby otrzymać ostatni dzień jako obiekt Date:
źródło
Możesz ustawić kalendarz na pierwszy dzień następnego miesiąca, a następnie odjąć dzień.
Po uruchomieniu tego kodu nextNotifTime zostanie ustawiony na ostatni dzień bieżącego miesiąca. Pamiętaj, że jeśli dzisiaj jest ostatni dzień miesiąca, efekt netto tego kodu jest taki, że obiekt Calendar pozostaje niezmieniony.
źródło
Poniższe zawsze zapewniają prawidłowe wyniki:
źródło
Korzystanie z najnowszej
java.time
biblioteki tutaj jest najlepszym rozwiązaniem:Alternatywnie możesz:
źródło
Możesz również użyć YearMonth.
Lubić:
Zobacz https://docs.oracle.com/javase/8/docs/api/java/time/YearMonth.html#atEndOfMonth--
źródło
Spójrz na
getActualMaximum(int field)
metodę obiektu Calendar.Jeśli ustawisz obiekt kalendarza na miesiąc, dla którego szukasz ostatniej daty,
getActualMaximum(Calendar.DAY_OF_MONTH)
poda ci ostatni dzień.źródło
źródło
Wdrożenie rozszerzenia daty Kotlin przy użyciu
java.util.Calendar
Możesz wywołać
toEndOfMonth
funkcję dla każdego obiektu Date, takiego jakDate().toEndOfMonth()
źródło