Отримайте перший та останній день місяця, використовуючи тритен, LocalDate


127

У мене є LocalDate, який повинен отримати перший і останній день місяця. Як це зробити?

напр. 13/2/2014 Мені потрібно отримати 1/2/2014і 28/2/2014у форматах LocalDate .

Використання триденного класу LocalDate.

Відповіді:


180

Просто використовуйте withDayOfMonthта lengthOfMonth():

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

3
FYI бачу інші відповіді
assylias

147

API був розроблений, щоб підтримувати рішення, що відповідає вимогам бізнесу

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

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

Однак рішення Джона також чудові.


5
Ідучи з цим, використовує ресурси API, спеціально створені для вирішення цієї конкретної проблеми.
jpangamarca

87

YearMonth

Для повноти та більш елегантності, на мою думку, дивіться це використання YearMonthкласу.

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

Для першого та останнього дня поточного місяця це стає:

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

8
Найкраще рішення з усіх.
Август Санчес

Додаткова інформація: YearMonth yearMonth = YearMonth.parse ("202004", DateTimeFormatter.ofPattern ("yyyyMM"));
egemen

які переваги цього порівняно з LocalDate withметодом?
AndrewBloom

@AndrewBloom вам не потрібно використовувати статичну функцію, щоб отримати останній день місяця, і, принаймні, у другому прикладі, вам не потрібно мати LocalDateпримірник для початку.
герман

18

Відповідь Джона Скітса є правильною і заслужив мою нагоду, просто додавши це дещо інше рішення для повноти:

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
Шановний дайвотер, чесно кажучи, я не розумію низового голосу, тому що моя відповідь була навіть за день до відповіді JodaStephen і вказала на головну цікаву нову частину, а саме на тимчасового регулятора на кінець місяця. Тобто я не "скопіював" відповідь ні від кого іншого.
Мено Хохшильд

Чудова відповідь! Це рішення краще, тому що рекомендується в документах : "... пошук першого або останнього дня місяця"
петерчаула

4

Якщо хтось приходить шукати перший день попереднього місяця та останній день попереднього місяця :

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


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

Хороший код, але в Stack Overflow відповідь має відповідати специфіці питання.
Василь Бурк

Дякую, я згоден Іноді ми знаходимо відповідний код у потоці, тому що я також шукав це. Я просто ставлю це для таких користувачів. Сподіваюся, що це нормально. Дякую.
Аніл Бхаскар

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

Опишіть, будь ласка, свою відповідь
smilyface

1

Ви можете спробувати це, щоб уникнути вказівки на власну дату, а якщо є необхідність відображати дати початку та кінця поточного місяця:

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

Результат:

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

1
Мені це здається трохи ускладненим. Це також не дає правильного результату. Останній день цього місяця - 2019-12-31, але ваш фрагмент друкується 2019-12-30.
Оле ВВ

0

Спробуйте це:

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

ви можете знайти вихід бажання, але потрібно подбати про параметр true / false для getLastDayOfMonth методу

цей параметр позначає високосний рік


Не потрібно користуватися getLastDayOfMonth- дивіться мою відповідь для більш простого підходу.
Джон Скіт

0

якщо ви хочете зробити це лише з класом 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);

0

Просто тут, щоб показати мою реалізацію рішення @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тут використовується саме той неправильний клас. Ви відкидаєте цінну інформацію про зону / зміщення.
Василь Бурк

Питання задає значення лише для дати, а не значення для дати, яке ви шукаєте тут. І страшний клас спадщини Dateне має нічого спільного з Питанням, і його взагалі слід уникати.
Василь Бурк

1
Для часового поясу Ла-Пас, будь ласка, скористайтеся правильнішим ZoneId.of("America/La_Paz"). Для сучасних дат це буде такий же результат, але, можливо, не для історичних дат чи дат у подальшому майбутньому.
Оле ВВ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.