Получение первого и последнего дня месяца в Java threeten
Быстрый ответ
Для определения первого и последнего дня текущего месяца можно воспользоваться классами LocalDate
и YearMonth
следующим образом:
localDate.withDayOfMonth(1)
: Получение первого дня месяца.yearMonth.atEndOfMonth()
: Получение последнего дня месяца.
import org.threeten.bp.LocalDate;
import org.threeten.bp.YearMonth;
LocalDate today = LocalDate.now();
LocalDate firstDay = today.withDayOfMonth(1);
LocalDate lastDay = YearMonth.from(today).atEndOfMonth();
Такой код позволяет получить даты начала и окончания текущего месяца для структур типа LocalDate
.
Заглубляемся: Немного о TemporalAdjusters
Пользуюя TemporalAdjusters
, можно сделать работу с датами более гибкой:
import org.threeten.bp.temporal.TemporalAdjusters;
LocalDate firstDayAdjusted = today.with(TemporalAdjusters.firstDayOfMonth());
LocalDate lastDayAdjusted = today.with(TemporalAdjusters.lastDayOfMonth());
Для повышения читабельности и удобства поддрежки кода рассмотрите использование статического импорта:
import static org.threeten.bp.temporal.TemporalAdjusters.firstDayOfMonth;
import static org.threeten.bp.temporal.TemporalAdjusters.lastDayOfMonth;
LocalDate firstDayClean = today.with(firstDayOfMonth());
LocalDate lastDayClean = today.with(lastDayOfMonth());
Использование этих методов позволяет принимать во внимание особенности високосных годов, включая дополнительный день в феврале.
В некоторых случаях может быть полезным использовать класс YearMonth
:
YearMonth yearMonthInstance = YearMonth.from(today);
LocalDate firstDayYearMonth = yearMonthInstance.atDay(1);
LocalDate lastDayYearMonth = yearMonthInstance.atEndOfMonth();
YearMonth
идеально подходит для работы с месячными циклами, особенно в бизнес-логике.
На грани: Продвинутое использование и нестандарные случаи
Получение последнего дня, зная длину месяца
Если вам известна длина месяца, вы можете воспользоваться методом plusDays()
:
LocalDate lastDayKnownLength = firstDay.plusDays(monthLength – 1);
Учитывайте, что отсчёт начинается с первого дня, поэтому следует уменьшать общее число дней на единицу.
Создание даты вручную
Если требуется задать дату точно без учета текущего дня, работы способ:
LocalDate firstDaySpecific = LocalDate.of(year, month, 1);
LocalDate lastDaySpecific = firstDaySpecific.withDayOfMonth(
firstDaySpecific.lengthOfMonth()
);
При выборе способов работы с датами всегда обсуждайте его с учетом бизнес-правил.
Визуализация
Представьте LocalDate как временную шкалу, на которой отмечены начало и конец месяца:
📏 Временная шкала: Январь --------------------------------- Февраль --------------------------------- Март
Первый день: 📌 – это начало месяца
Январь: [📌, 2, 3, ..., 31]
Последний день: 🎯 – это окончание месяца
Январь: [1, ..., 30, 🎯]
При использовании LocalDate можно точно определить ключевые даты.
Взвешиваем преимущества: LocalDate
, TemporalAdjusters
и YearMonth
Читабельность превыше всего
Используя методы вроде .with(firstDayOfMonth())
, увеличивает понимание того, какие результаты можно ожидать от кода.
Оптимизация производительности
В средах с высокой нагрузков, сокращение числа вызовов методов в объектах типа LocalDate
, таких как .withDayOfMonth()
, может быть значимым.
Преимущество обслуживаемости
Использование статических импортов из TemporalAdjusters
или YearMonth
способствует поддержанию порядка в коде и создания модулей, которые могут использоваться самостоятельно.
Полезные материалы
- ThreeTen-Backport – домашняя страница — вход в мир API
java.time
для пользователей Java 6 & 7. - LocalDate (Java Platform SE 8) — официальная документация по Java LocalDate.
- SimpleDateFormat игнорирует месяц при парсинге (Stack Overflow) — обсуждение нюансов парсинга дат.
- Учебные пособия и примеры исходного кода — практические примеры для работы с датами в Java.
- DateTimeFormatter (Java Platform SE 8) — информация о форматировании дат с помощью DateTimeFormatter.
- Java LocalDate — подробное руководство по работе с LocalDate и LocalDateTime.