Mam LocalDate, który musi otrzymać pierwszy i ostatni dzień miesiąca. W jaki sposób mogę to zrobić?
na przykład. 13/2/2014
Muszę pobrać 1/2/2014
i 28/2/2014
w formatach LocalDate .
Korzystanie z trzech klas LocalDate.
Mam LocalDate, który musi otrzymać pierwszy i ostatni dzień miesiąca. W jaki sposób mogę to zrobić?
na przykład. 13/2/2014
Muszę pobrać 1/2/2014
i 28/2/2014
w formatach LocalDate .
Korzystanie z trzech klas LocalDate.
Odpowiedzi:
Interfejs API został zaprojektowany do obsługi rozwiązania, które jest ściśle dopasowane do wymagań biznesowych
import static java.time.temporal.TemporalAdjusters.*;
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.with(firstDayOfMonth());
LocalDate end = initial.with(lastDayOfMonth());
Jednak rozwiązania Jona są również w porządku.
YearMonth
Aby uzyskać kompletność i moim zdaniem bardziej eleganckie, zobacz użycie YearMonth
klasy.
YearMonth month = YearMonth.from(date);
LocalDate start = month.atDay(1);
LocalDate end = month.atEndOfMonth();
Dla pierwszego i ostatniego dnia bieżącego miesiąca jest to:
LocalDate start = YearMonth.now().atDay(1);
LocalDate end = YearMonth.now().atEndOfMonth();
LocalDate
with
metodą?
LocalDate
instancji, aby zacząć.
Odpowiedź Jona Skeetsa jest poprawna i zasłużyła na moją opinię, dodając tylko to nieco inne rozwiązanie dla kompletności:
import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;
LocalDate initial = LocalDate.of(2014, 2, 13);
LocalDate start = initial.withDayOfMonth(1);
LocalDate end = initial.with(lastDayOfMonth());
Jeśli ktoś przyjdzie szukać pierwszego dnia poprzedniego miesiąca i ostatniego dnia poprzedniego miesiąca :
public static LocalDate firstDayOfPreviousMonth(LocalDate date) {
return date.minusMonths(1).withDayOfMonth(1);
}
public static LocalDate lastDayOfPreviousMonth(LocalDate date) {
return date.withDayOfMonth(1).minusDays(1);
}
Możesz spróbować tego, aby uniknąć wskazywania niestandardowej daty i jeśli istnieje potrzeba wyświetlenia daty rozpoczęcia i zakończenia bieżącego miesiąca:
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);
Wynik:
> Start of month: 2019-12-01
> End of month: 2019-12-30
Spróbuj tego:
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);
możesz znaleźć pożądane wyjście, ale musisz zadbać o parametr true / false dla metody getLastDayOfMonth
ten parametr oznacza rok przestępny
getLastDayOfMonth
- zobacz moją odpowiedź, aby uzyskać prostsze podejście.
jeśli chcesz to zrobić tylko z klasą 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);
Tylko tutaj, aby pokazać moją implementację rozwiązania @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
jest dokładnie niewłaściwą klasą do użycia w tym miejscu. Odrzucasz cenne informacje o strefie / przesunięciu.
Date
nie ma nic wspólnego z pytaniem i generalnie należy jej unikać.
ZoneId.of("America/La_Paz")
. Dla dat dzisiejszych da ten sam wynik, ale może nie dla dat historycznych lub dat w dalszej przyszłości.