Класс Java LocalDate
LocalDate — это неизменяемый класс даты, введённый в Java 8, который относится кjava.timeпакет.
LocalDate представляет дату без часового пояса (год-месяц-день), например "2023-05-15". LocalDate не содержит информации о времени и часовом поясе, что делает его очень подходящим для сценариев, где требуются только даты, например дни рождения и праздники.
Основные особенности LocalDate
1. Неизменяемость
Экземпляры LocalDate неизменяемы; любая операция изменения возвращает новый объект LocalDate вместо изменения исходного объекта.
2. Потокобезопасность
Благодаря неизменяемости LocalDate является потокобезопасным и может безопасно использоваться в многопоточных средах.
3. Стандарт ISO-8601
LocalDate следует календарной системе ISO-8601, которая является международным стандартом для современного представления даты и времени.
Создание объектов LocalDate
1. Получение текущей даты
LocalDate today = LocalDate.now();
System.out.println("今天的日期: " + today);
2. Создание с конкретной датой
LocalDate specificDate = LocalDate.of(2023, Month.MAY, 15); // 或者 LocalDate specificDate2 = LocalDate.of(2023, 5, 15);
3. Парсинг из строки
LocalDate parsedDate = LocalDate.parse("2023-05-15");
Общие методы операций
1. Получение информации о дате
Пример
int year = date.getYear(); // 2023
Month month = date.getMonth(); // MAY
int day = date.getDayOfMonth(); // 15
DayOfWeek dow = date.getDayOfWeek(); // MONDAY
int len = date.lengthOfMonth(); // 31 (дней в мае)
boolean leap = date.isLeapYear(); // false (2023 не високосный год)
2. Сложение и вычитание дат
Пример
LocalDate nextWeek = today.plusWeeks(1);
LocalDate nextMonth = today.plusMonths(1);
LocalDate nextYear = today.plusYears(1);
LocalDate yesterday = today.minusDays(1);
3. Сравнение дат
Пример
LocalDate date2 = LocalDate.of(2023, 6, 20);
boolean isBefore = date1.isBefore(date2); // true
boolean isAfter = date1.isAfter(date2); // false
boolean isEqual = date1.isEqual(date2); // false
4. Корректировка дат
Пример
LocalDate firstDayOfMonth = date.withDayOfMonth(1);
LocalDate lastDayOfYear = date.with(TemporalAdjusters.lastDayOfYear());
Форматирование и парсинг
1. Форматирование дат
Пример
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formattedDate = date.format(formatter);
2. Парсинг строки в дату
Пример
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date = LocalDate.parse(dateStr, formatter);
Примеры практического применения
1. Вычисление количества дней между двумя датами
Пример
LocalDate endDate = LocalDate.of(2023, 5, 15);
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("Разница в днях: " + daysBetween);
2. Проверка, находится ли дата в диапазоне
Пример
LocalDate startDate = LocalDate.of(2023, 5, 1);
LocalDate endDate = LocalDate.of(2023, 5, 31);
if (dateToCheck.isAfter(startDate) && dateToCheck.isBefore(endDate)) {
System.out.println("Дата находится в диапазоне");
}
3. Получение всех дат месяца
Пример
int daysInMonth = date.lengthOfMonth();
for (int i = 1; i <= daysInMonth; i++) {
System.out.println(date.withDayOfMonth(i));
}
Комплексный пример
Пример
import java.time.Month;
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
public class LocalDateDemo {
public static void main(String[] args) {
// 1. Создание экземпляров LocalDate
System.out.println("=== Создание экземпляров LocalDate ===");
LocalDate today = LocalDate.now();
LocalDate specificDate = LocalDate.of(2023, Month.JULY, 15);
LocalDate parsedDate = LocalDate.parse("2023-08-20");
System.out.println("Текущая дата: " + today);
System.out.println("Конкретная дата: " + specificDate);
System.out.println("Разобранная дата: " + parsedDate);
// 2. Получение информации о дате
System.out.println("\n=== Получение информации о дате ===);
System.out.println("Год: " + today.getYear());
System.out.println("Месяц: " + today.getMonth() + " (" + today.getMonthValue() + ")");
System.out.println("День: " + today.getDayOfMonth());
System.out.println("День недели: " + today.getDayOfWeek());
System.out.println("День года: " + today.getDayOfYear());
System.out.println("Дней в месяце: " + today.lengthOfMonth());
System.out.println("Дней в году: " + today.lengthOfYear());
System.out.println("Високосный год: " + today.isLeapYear());
// 3. Вычисление даты
System.out.println("\n=== Вычисление даты ===);
System.out.println("Плюс 5 дней: " + today.plusDays(5));
System.out.println("Плюс 2 недели: " + today.plusWeeks(2));
System.out.println("Плюс 3 месяца: " + today.plusMonths(3));
System.out.println("Минус 1 год: " + today.minusYears(1));
System.out.println("Первый день следующего месяца: " + today.plusMonths(1).withDayOfMonth(1));
System.out.println("Последний день этого месяца: " + today.withDayOfMonth(today.lengthOfMonth()));
// 4. Сравнение дат
System.out.println("\n=== Сравнение дат ===);
LocalDate date1 = LocalDate.of(2023, 6, 15);
LocalDate date2 = LocalDate.of(2023, 6, 20);
System.out.println(date1 + " — это " + date2 + " раньше? " + date1.isBefore(date2));
System.out.println(date1 + " — это " + date2 + " позже? " + date1.isAfter(date2));
System.out.println(date1 + " равно " + date2 + "? " + date1.isEqual(date2));
// 5. Вычисление разницы дат
System.out.println("\n=== Расчёт разницы дат ===);
LocalDate startDate = LocalDate.of(2023, 1, 1);
LocalDate endDate = LocalDate.of(2023, 12, 31);
System.out.println("Количество дней между двумя датами: " + ChronoUnit.DAYS.between(startDate, endDate));
System.out.println("Количество месяцев между двумя датами: " + ChronoUnit.MONTHS.between(startDate, endDate));
System.out.println("Количество лет между двумя датами: " + ChronoUnit.YEARS.between(startDate, endDate));
// 6. Форматирование даты
System.out.println("\n=== Форматирование даты ===);
DateTimeFormatter basicFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern(yyyy-MM-dd EEEE, Locale.CHINA);
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy", Locale.US);
System.out.println("Базовый формат: " + today.format(basicFormatter));
System.out.println("Китайский формат: " + today.format(chineseFormatter));
System.out.println("Английский формат: " + today.format(customFormatter));
// 7. Другие полезные методы
System.out.println("\n=== Другие полезные методы ===);
System.out.println("Скорректировано на следующий понедельник: " + today.with(DayOfWeek.MONDAY));
System.out.println("Это выходной: " +
(today.getDayOfWeek() == DayOfWeek.SATURDAY || today.getDayOfWeek() == DayOfWeek.SUNDAY));
// 8. Итерация по диапазону дат
System.out.println("\n=== Итерация по диапазону дат ===);
System.out.println("Даты на следующие 7 дней:");
today.datesUntil(today.plusDays(7))
.forEach(System.out::println);
}
}
Вывод будет похож на следующий:
=== 创建 LocalDate 实例 === 当前日期: 2023-06-15 特定日期: 2023-07-15 解析日期: 2023-08-20 === 获取日期信息 === 年: 2023 月: JUNE (6) 日: 15 星期: THURSDAY 一年中的第几天: 166 月份天数: 30 年份天数: 365 是否闰年: false === 日期计算 === 加5天: 2023-06-20 加2周: 2023-06-29 加3个月: 2023-09-15 减1年: 2022-06-15 下个月的第一天: 2023-07-01 本月的最后一天: 2023-06-30 === 日期比较 === 2023-06-15 在 2023-06-20 之前? true 2023-06-15 在 2023-06-20 之后? false 2023-06-15 等于 2023-06-20? false === 计算日期差 === 两个日期之间的天数: 364 两个日期之间的月数: 11 两个日期之间的年数: 0 === 日期格式化 === 基本格式: 2023/06/15 中文格式: 2023年06月15日 星期四 英文格式: Jun 15, 2023 === 其他实用方法 === 调整到下个星期一: 2023-06-19 是否是周末: false === 日期范围迭代 === 接下来7天的日期: 2023-06-15 2023-06-16 2023-06-17 2023-06-18 2023-06-19 2023-06-20 2023-06-21
Итог
Класс LocalDate — важная часть Java 8 Date-Time API. Он предоставляет богатый набор методов для работы с операциями, связанными с датами. По сравнению со старыми классами Date и Calendar, LocalDate более интуитивен, проще в использовании и потокобезопасен. Освоение LocalDate может значительно повысить эффективность работы с датами и читаемость кода.
Ниже перечислены его распространённые методы:
Статические фабричные методы
| Метод | Описание | Пример |
|---|---|---|
static LocalDate now() |
Получить текущую дату | LocalDate.now() |
static LocalDate of(int year, int month, int dayOfMonth) |
Создать с указанным годом, месяцем и днём | LocalDate.of(2023, 6, 15) |
static LocalDate of(int year, Month month, int dayOfMonth) |
Создать с указанным годом, месяцем и днём (с использованием перечисления Month) | LocalDate.of(2023, Month.JUNE, 15) |
static LocalDate parse(CharSequence text) |
Разобрать из строки (формат ISO: yyyy-MM-dd) | LocalDate.parse("2023-06-15") |
static LocalDate parse(CharSequence text, DateTimeFormatter formatter) |
Разобрать с использованием указанного формата | LocalDate.parse("15/06/2023", DateTimeFormatter.ofPattern("dd/MM/yyyy")) |
Получение информации о дате
| Метод | Описание | Пример |
|---|---|---|
int getYear() |
Получить год | 2023 |
Month getMonth() |
Получить месяц (перечисление Month) | Month.JUNE |
int getMonthValue() |
Получить значение месяца (1-12) | 6 |
int getDayOfMonth() |
Получить день месяца | 15 |
int getDayOfYear() |
Получить день года | 166 |
DayOfWeek getDayOfWeek() |
Получить день недели (перечисление DayOfWeek) | DayOfWeek.THURSDAY |
int lengthOfMonth() |
Вернуть количество дней в месяце | 30 |
int lengthOfYear() |
Вернуть количество дней в году (365 или 366) | 365 |
boolean isLeapYear() |
Проверить, является ли год високосным | false |
Операции с датой
| Метод | Описание | Пример |
|---|---|---|
LocalDate plusDays(long days) |
Добавить дни | date.plusDays(5) |
LocalDate plusWeeks(long weeks) |
Добавить недели | date.plusWeeks(2) |
LocalDate plusMonths(long months) |
Добавить месяцы | date.plusMonths(3) |
LocalDate plusYears(long years) |
Добавить годы | date.plusYears(1) |
LocalDate minusDays(long days) |
Вычесть дни | date.minusDays(5) |
LocalDate minusWeeks(long weeks) |
Вычесть недели | date.minusWeeks(2) |
LocalDate minusMonths(long months) |
Вычесть месяцы | date.minusMonths(3) |
LocalDate minusYears(long years) |
Вычесть годы | date.minusYears(1) |
LocalDate withDayOfMonth(int dayOfMonth) |
Изменить день месяца | date.withDayOfMonth(1) |
LocalDate withDayOfYear(int dayOfYear) |
Изменить день года | date.withDayOfYear(100) |
LocalDate withMonth(int month) |
Изменить месяц | date.withMonth(12) |
LocalDate withYear(int year) |
Изменить год | date.withYear(2024) |
Сравнение дат
| Метод | Описание | Пример |
|---|---|---|
boolean isAfter(ChronoLocalDate other) |
Проверить, находится ли после указанной даты | date1.isAfter(date2) |
boolean isBefore(ChronoLocalDate other) |
Проверить, находится ли дата до указанной даты | date1.isBefore(date2) |
boolean isEqual(ChronoLocalDate other) |
Проверить, равна ли дата указанной дате | date1.isEqual(date2) |
long until(ChronoLocalDate endDate, ChronoUnit unit) |
Вычислить количество времени между двумя датами | date1.until(date2, ChronoUnit.DAYS) |
Форматирование и преобразование
| Метод | Описание | Пример |
|---|---|---|
String format(DateTimeFormatter formatter) |
Форматировать как строку | date.format(DateTimeFormatter.ISO_DATE) |
String toString() |
Преобразовать в строку формата ISO (yyyy-MM-dd) | "2023-06-15" |
long toEpochDay() |
Преобразовать в число дней с 1970-01-01 | 19531 |
LocalDateTime atTime(int hour, int minute) |
Преобразовать в LocalDateTime | date.atTime(14, 30) |
LocalDateTime atTime(LocalTime time) |
Преобразовать в LocalDateTime | date.atTime(LocalTime.now()) |
Другие полезные методы
| Метод | Описание | Пример |
|---|---|---|
boolean isSupported(ChronoUnit unit) |
Проверить, поддерживается ли единица времени | date.isSupported(ChronoUnit.DAYS) |
boolean isSupported(ChronoField field) |
Проверить, поддерживается ли поле времени | date.isSupported(ChronoField.HOUR_OF_DAY) |
LocalDate with(TemporalAdjuster adjuster) |
Скорректировать дату с помощью корректировщика | date.with(TemporalAdjusters.firstDayOfMonth()) |
Java java.nio.file.Files