Класс LocalDate в Java: методы и примеры - Вопросы

Всего: 5 вопросов

1. 

Как создать объект LocalDate в Java?

Публичного конструктора у LocalDate нет — объект создаётся статическими фабричными методами:

  • LocalDate.of(2024, 3, 15) или LocalDate.of(2024, Month.MARCH, 15) — конкретная дата (месяцы нумеруются с 1);
  • LocalDate.now() — текущая дата в зоне JVM по умолчанию, LocalDate.now(ZoneId.of("Asia/Tokyo")) — в указанной зоне;
  • LocalDate.parse("2024-03-15") — разбор строки в формате ISO-8601 yyyy-MM-dd;
  • LocalDate.ofYearDay(2001, 32) (2001-02-01) и LocalDate.ofEpochDay(0) (1970-01-01).

Несуществующая дата не «перетекает» на следующий месяц: LocalDate.of(2023, 2, 29) выбрасывает DateTimeException, а LocalDate.parse("2023-1-5") — DateTimeParseException.

2. 

Почему после вызова date.plusDays(1); значение date не меняется?

LocalDate неизменяем. Методы plus...(), minus...() и with...() не меняют объект, а возвращают новую дату. Если результат не присвоить, он теряется:

date.plusDays(1);        // результат потерян
date = date.plusDays(1); // правильно

Благодаря неизменяемости LocalDate потокобезопасен: один объект можно использовать из нескольких потоков без синхронизации и хранить в static final поле.

3. 

Как сравнить две даты LocalDate и почему нельзя использовать ==?

Для сравнения служат методы isBefore(), isAfter() и isEqual(), которые возвращают boolean; на равенство можно проверять и через equals(). Оператор == сравнивает ссылки, а не значения, поэтому для двух разных объектов с одинаковой датой обычно даёт false.

Для сортировки используется compareTo() (LocalDate реализует Comparable). Он возвращает не строго -1/0/1, а разницу: LocalDate.of(2001, 1, 1).compareTo(LocalDate.of(2005, 6, 1)) вернёт -4. Поэтому результат сравнивают с нулём (< 0, > 0), а не с -1.

4. 

Как посчитать количество дней между двумя датами LocalDate?

Используйте ChronoUnit.DAYS.between(start, end) или эквивалентный start.until(end, ChronoUnit.DAYS):

LocalDate start = LocalDate.of(2001, 1, 1);
LocalDate end = LocalDate.of(2001, 3, 1);
ChronoUnit.DAYS.between(start, end); // 59
ChronoUnit.DAYS.between(end, start); // -59

Результат имеет тип long, конечная дата в подсчёт не входит, а если конец раньше начала, число отрицательное. Аналогично считаются месяцы и годы: ChronoUnit.MONTHS.between(start, end) вернёт 2.

5. 

Как конвертировать LocalDate в java.util.Date и java.sql.Date и обратно?

java.util.Date — момент времени, а у LocalDate нет ни времени, ни зоны, поэтому при конвертации нужно выбрать зону:

ZoneId zone = ZoneId.systemDefault();
Date utilDate = Date.from(localDate.atStartOfDay(zone).toInstant()); // полночь в зоне zone
LocalDate back = utilDate.toInstant().atZone(zone).toLocalDate();

С java.sql.Date зона не нужна: java.sql.Date.valueOf(localDate) и sqlDate.toLocalDate(). Метод sqlDate.toInstant() выбрасывает UnsupportedOperationException. Конвертируйте туда и обратно с одной и той же ZoneId, иначе дата может сдвинуться на день.

Страница 1 из 1