Статьи

Полный курс по языку Java — от установки JDK до многопоточности и HTTP-запросов

Дата и время

Страница 26 из 30 · 2026-10-25 · 5 мин чтения

Пакет java.time

Начиная с Java 8 для работы с датой и временем используется java.time. Старые Date и Calendar применять не стоит. Все классы java.time неизменяемы и потокобезопасны.

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

LocalDate

import java.time.DayOfWeek;import java.time.LocalDate;import java.time.Month;public class LocalDateDemo {    public static void main(String[] args) {        LocalDate today = LocalDate.now();        LocalDate date = LocalDate.of(2026, 10, 25);        LocalDate parsed = LocalDate.parse("2026-12-31");        System.out.println(today.getYear() > 2000);        System.out.println(date.getMonth());        System.out.println(date.getMonthValue());        System.out.println(date.getDayOfMonth());        System.out.println(date.getDayOfWeek());        System.out.println(date.getDayOfYear());        System.out.println(date.isLeapYear());        System.out.println(date.lengthOfMonth());        LocalDate nextWeek = date.plusDays(7);        LocalDate lastMonth = date.minusMonths(1);        LocalDate nextYear = date.plusYears(1);        LocalDate firstOfMonth = date.withDayOfMonth(1);        System.out.println(nextWeek + " " + lastMonth + " " + nextYear + " " + firstOfMonth);        System.out.println(date.isBefore(parsed));        System.out.println(date.isAfter(parsed));        System.out.println(date.equals(LocalDate.of(2026, Month.OCTOBER, 25)));        System.out.println(date.getDayOfWeek() == DayOfWeek.SUNDAY);    }}

Месяцы нумеруются с 1.

LocalTime и LocalDateTime

import java.time.LocalDate;import java.time.LocalDateTime;import java.time.LocalTime;public class LocalTimeDemo {    public static void main(String[] args) {        LocalTime time = LocalTime.of(14, 30, 15);        System.out.println(time);        System.out.println(time.plusHours(2));        System.out.println(time.minusMinutes(45));        System.out.println(time.isAfter(LocalTime.NOON));        LocalDateTime dateTime = LocalDateTime.of(2026, 10, 25, 9, 0);        System.out.println(dateTime);        System.out.println(dateTime.toLocalDate());        System.out.println(dateTime.toLocalTime());        System.out.println(LocalDateTime.of(LocalDate.of(2027, 1, 1), LocalTime.MIDNIGHT));        System.out.println(dateTime.plusDays(1).withHour(18));    }}

Часовые пояса

import java.time.Instant;import java.time.LocalDateTime;import java.time.ZoneId;import java.time.ZonedDateTime;public class ZoneDemo {    public static void main(String[] args) {        ZonedDateTime berlin = ZonedDateTime.of(            LocalDateTime.of(2026, 10, 25, 12, 0),            ZoneId.of("Europe/Berlin")        );        ZonedDateTime tokyo = berlin.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));        ZonedDateTime newYork = berlin.withZoneSameInstant(ZoneId.of("America/New_York"));        System.out.println(berlin);        System.out.println(tokyo);        System.out.println(newYork);        Instant instant = berlin.toInstant();        System.out.println(instant);        System.out.println(instant.getEpochSecond());        System.out.println(Instant.ofEpochSecond(0));        System.out.println(ZoneId.systemDefault());    }}

Для хранения и передачи моментов времени между системами используйте Instant или значения в UTC. Часовой пояс применяйте при показе пользователю.

Duration и Period

import java.time.Duration;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.Period;import java.time.temporal.ChronoUnit;public class DurationDemo {    public static void main(String[] args) {        LocalDateTime start = LocalDateTime.of(2026, 10, 25, 9, 0);        LocalDateTime end = LocalDateTime.of(2026, 10, 25, 17, 45);        Duration duration = Duration.between(start, end);        System.out.println(duration);        System.out.println(duration.toHours());        System.out.println(duration.toMinutes());        System.out.println(duration.toMinutesPart());        LocalDate birth = LocalDate.of(1995, 3, 14);        LocalDate now = LocalDate.of(2026, 10, 25);        Period period = Period.between(birth, now);        System.out.println(period.getYears() + " лет, " + period.getMonths() + " мес., " + period.getDays() + " дн.");        System.out.println(ChronoUnit.DAYS.between(birth, now));        System.out.println(ChronoUnit.MONTHS.between(birth, now));        Duration custom = Duration.ofMinutes(90);        System.out.println(custom.plusSeconds(30));    }}

Duration измеряет время на уровне секунд и наносекунд, а Period — календарные единицы.

Форматирование и разбор

import java.time.LocalDate;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;import java.time.format.DateTimeParseException;import java.util.Locale;public class FormatDemo {    public static void main(String[] args) {        LocalDateTime dt = LocalDateTime.of(2026, 10, 25, 14, 5, 9);        DateTimeFormatter f1 = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");        DateTimeFormatter f2 = DateTimeFormatter.ofPattern("d MMMM yyyy, EEEE", Locale.forLanguageTag("ru"));        System.out.println(dt.format(f1));        System.out.println(dt.format(f2));        System.out.println(dt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));        LocalDate parsed = LocalDate.parse("25.10.2026", DateTimeFormatter.ofPattern("dd.MM.yyyy"));        System.out.println(parsed);        try {            LocalDate.parse("2026/10/25");        } catch (DateTimeParseException e) {            System.out.println("Неверный формат: " + e.getParsedString());        }    }}

Основные символы шаблона:

СимволЗначениеПример
yyyyгод2026
MMмесяц числом10
MMMMназвание месяцаоктября
ddдень месяца25
EEEEдень неделивоскресенье
HHчасы 0–2314
hhчасы 1–1202
mmминуты05
ssсекунды09
aAM/PMPM

Форматтеры потокобезопасны, их можно хранить в static final полях. В отличие от SimpleDateFormat.

Корректировщики дат

import java.time.DayOfWeek;import java.time.LocalDate;import java.time.temporal.TemporalAdjusters;public class AdjustersDemo {    public static void main(String[] args) {        LocalDate date = LocalDate.of(2026, 10, 25);        System.out.println(date.with(TemporalAdjusters.firstDayOfMonth()));        System.out.println(date.with(TemporalAdjusters.lastDayOfMonth()));        System.out.println(date.with(TemporalAdjusters.next(DayOfWeek.MONDAY)));        System.out.println(date.with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY)));        System.out.println(date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)));    }}

Измерение времени выполнения

import java.time.Duration;import java.time.Instant;public class Timing {    public static void main(String[] args) {        Instant start = Instant.now();        long sum = 0;        for (int i = 0; i < 100_000_000; i++) {            sum += i;        }        Duration elapsed = Duration.between(start, Instant.now());        System.out.println(sum);        System.out.println(elapsed.toMillis() + " мс");        long t0 = System.nanoTime();        long t1 = System.nanoTime();        System.out.println((t1 - t0) + " нс");    }}

Для замера интервалов используйте System.nanoTime() или Instant, а System.currentTimeMillis() лучше оставить для получения текущего времени.

Рабочие дни: пример

import java.time.DayOfWeek;import java.time.LocalDate;public class Workdays {    static LocalDate addWorkdays(LocalDate start, int days) {        LocalDate date = start;        int added = 0;        while (added < days) {            date = date.plusDays(1);            DayOfWeek day = date.getDayOfWeek();            if (day != DayOfWeek.SATURDAY && day != DayOfWeek.SUNDAY) {                added++;            }        }        return date;    }    public static void main(String[] args) {        System.out.println(addWorkdays(LocalDate.of(2026, 10, 23), 5));    }}

Устаревшие классы

В старом коде встречаются java.util.Date, Calendar, SimpleDateFormat. Они изменяемые, непотокобезопасные и неудобные. Преобразование к современному API:

import java.time.Instant;import java.time.ZoneId;import java.time.ZonedDateTime;import java.util.Date;public class LegacyDate {    public static void main(String[] args) {        Date legacy = new Date();        Instant instant = legacy.toInstant();        ZonedDateTime zoned = instant.atZone(ZoneId.systemDefault());        Date back = Date.from(instant);        System.out.println(zoned.getYear() > 2000);        System.out.println(back.equals(legacy));    }}