Работа с датами в Java: обзор библиотек java.time, Joda-Time и Apache Commons

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с датами в Java: обзор современных библиотек и инструментов

Работа с датами и временем — одна из самых частых задач в разработке на Java. Долгое время стандартные классы java.util.Date и java.util.Calendar были неудобными, mutable (изменяемыми) и подверженными ошибкам. К счастью, ситуация изменилась. В этом обзоре мы рассмотрим три основных подхода: встроенный пакет java.time, библиотеку Joda-Time и утилиты Apache Commons Lang.

1. java.time (Java 8+) — современный стандарт

Начиная с Java 8, в стандартную библиотеку вошёл пакет java.time, основанный на идеях Joda-Time. Это основной и рекомендуемый способ работы с датами в новых проектах.

Ключевые классы:

  • LocalDate — дата без времени (год, месяц, день).
  • LocalTime — время без даты (часы, минуты, секунды, наносекунды).
  • LocalDateTime — объединение даты и времени.
  • ZonedDateTime — дата и время с учётом часового пояса.
  • Instant — момент времени в UTC (машиночитаемый).
  • Duration и Period — для работы с промежутками времени.

Примеры использования:

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class JavaTimeExample {
    public static void main(String[] args) {
        // Текущая дата и время
        LocalDate today = LocalDate.now();
        LocalTime now = LocalTime.now();
        System.out.println("Сегодня: " + today);
        System.out.println("Сейчас: " + now);

        // Создание конкретной даты
        LocalDate birthDate = LocalDate.of(1990, Month.MAY, 15);
        System.out.println("Дата рождения: " + birthDate);

        // Работа с часовыми поясами
        ZonedDateTime berlinTime = ZonedDateTime.now(ZoneId.of("Europe/Berlin"));
        ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        System.out.println("В Берлине: " + berlinTime);
        System.out.println("В Токио: " + tokyoTime);

        // Разница между датами
        long daysBetween = ChronoUnit.DAYS.between(birthDate, today);
        System.out.println("Дней с дня рождения: " + daysBetween);

        // Форматирование
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
        String formatted = LocalDateTime.now().format(formatter);
        System.out.println("Отформатировано: " + formatted);

        // Парсинг строки
        LocalDate parsedDate = LocalDate.parse("2023-12-31");
        System.out.println("Распарсено: " + parsedDate);
    }
}

2. Joda-Time — проверенная временем альтернатива

До выхода Java 8, Joda-Time была де-факто стандартом для работы с датами. Сейчас её использование оправдано только в legacy-проектах или при необходимости поддержки старых версий Java (ниже 8).

Основные особенности:

  • Неизменяемые (immutable) объекты — потокобезопасность.
  • Поддержка множества календарных систем (исламский, буддийский и др.).
  • Простой и интуитивный API.

Пример кода с Joda-Time:

import org.joda.time.*;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class JodaTimeExample {
    public static void main(String[] args) {
        // Текущая дата и время
        DateTime now = DateTime.now();
        System.out.println("Сейчас: " + now);

        // Создание даты
        DateTime specificDate = new DateTime(2020, 6, 15, 10, 30, 0);
        System.out.println("Конкретная дата: " + specificDate);

        // Прибавление дней
        DateTime nextWeek = now.plusWeeks(1);
        System.out.println("Через неделю: " + nextWeek);

        // Разница между датами
        Days daysBetween = Days.daysBetween(specificDate, now);
        System.out.println("Разница в днях: " + daysBetween.getDays());

        // Форматирование
        DateTimeFormatter fmt = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm");
        String formatted = now.toString(fmt);
        System.out.println("Формат: " + formatted);
    }
}

Подключение (Maven):

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.12.5</version>
</dependency>

3. Apache Commons Lang — вспомогательные утилиты

Рекомендаций