Класс 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. Получение информации о дате

Пример

LocalDate date = LocalDate.of(2023, 5, 15);
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 tomorrow = today.plusDays(1);
LocalDate nextWeek = today.plusWeeks(1);
LocalDate nextMonth = today.plusMonths(1);
LocalDate nextYear = today.plusYears(1);
LocalDate yesterday = today.minusDays(1);

3. Сравнение дат

Пример

LocalDate date1 = LocalDate.of(2023, 5, 15);
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 date = LocalDate.of(2023, 5, 15);
LocalDate firstDayOfMonth = date.withDayOfMonth(1);
LocalDate lastDayOfYear = date.with(TemporalAdjusters.lastDayOfYear());

Форматирование и парсинг

1. Форматирование дат

Пример

LocalDate date = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formattedDate = date.format(formatter);

2. Парсинг строки в дату

Пример

String dateStr = "2023/05/15";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date = LocalDate.parse(dateStr, formatter);

Примеры практического применения

1. Вычисление количества дней между двумя датами

Пример

LocalDate startDate = LocalDate.of(2023, 5, 1);
LocalDate endDate = LocalDate.of(2023, 5, 15);
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("Разница в днях: " + daysBetween);

2. Проверка, находится ли дата в диапазоне

Пример

LocalDate dateToCheck = LocalDate.of(2023, 5, 10);
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. Получение всех дат месяца

Пример

LocalDate date = LocalDate.of(2023, 5, 1);
int daysInMonth = date.lengthOfMonth();

for (int i = 1; i <= daysInMonth; i++) {
    System.out.println(date.withDayOfMonth(i));
}

Комплексный пример

Пример

import java.time.LocalDate;
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 File Java java.nio.file.Files

Другие расширения