Пакет java.time
Основной API для дат, времени, моментов времени и длительностей.
Определенные здесь классы представляют основные понятия даты и времени, включая моменты времени, длительности, даты, время, часовые пояса и периоды. Они основаны на календарной системе ISO, которая является фактически всемирным календарем, следующим правилам пролептического григорианского календаря. Все классы неизменяемы и потокобезопасны.
Каждый экземпляр даты и времени состоит из полей, доступных через API. Для доступа к полям на более низком уровне обратитесь к пакету java.time.temporal. Каждый класс поддерживает печать и разбор самых разных дат и времени. Варианты настройки описаны в пакете java.time.format.
Пакет java.time.chrono содержит независимый от календаря API: ChronoLocalDate, ChronoLocalDateTime, ChronoZonedDateTime и Era. Он предназначен для приложений, которым необходимо использовать локализованные календари. Рекомендуется использовать классы даты и времени ISO-8601 из этого пакета при взаимодействии через границы систем, например с базой данных или по сети. Независимый от календаря API следует использовать для взаимодействия с пользователями.
Даты и время
Instant — это, по сути, числовая отметка времени. Текущий момент времени можно получить из Clock. Это удобно для ведения журналов и сохранения момента времени; ранее такой момент связывали с сохранением результата вызова System.currentTimeMillis().
LocalDate хранит дату без времени. Например, она может хранить дату '2010-12-03' и использоваться для хранения дня рождения.
LocalTime хранит время без даты. Например, оно может хранить время '11:30' и использоваться для хранения времени открытия или закрытия.
LocalDateTime хранит дату и время. Например, оно может хранить дату и время '2010-12-03T11:30'.
ZonedDateTime хранит дату и время с часовым поясом. Это полезно, если требуется выполнять точные вычисления дат и времени с учетом ZoneId, например 'Europe/Paris'. По возможности рекомендуется использовать более простой класс без часового пояса. Широкое использование часовых поясов обычно значительно усложняет приложение.
Длительность и период
Помимо дат и времени, API также позволяет хранить периоды и длительности времени. Duration — это простая мера времени на временной шкале, выраженная в наносекундах. Period выражает количество времени в единицах, значимых для человека, например в годах или днях.
Дополнительные типы значений
Month хранит месяц отдельно. Например, он хранит отдельный месяц года, такой как 'DECEMBER'.
DayOfWeek хранит день недели отдельно. Например, он хранит отдельный день недели, такой как 'TUESDAY'.
Year хранит год отдельно. Например, он хранит отдельный год, такой как '2010'.
YearMonth хранит год и месяц без дня или времени. Например, он хранит год и месяц '2010-12' и может использоваться для хранения срока действия кредитной карты.
MonthDay хранит месяц и день без года или времени. Например, он хранит месяц и день месяца '--12-03' и может использоваться для хранения ежегодного события, например дня рождения, без указания года.
OffsetTime хранит время и смещение от UTC без даты. Например, оно хранит время '11:30+01:00'. ZoneOffset имеет формат '+01:00'.
OffsetDateTime хранит дату, время и смещение от UTC. Например, оно хранит дату и время '2010-12-03T11:30+01:00'. Этот тип иногда встречается в сообщениях XML и других формах хранения данных, но содержит меньше информации, чем полный часовой пояс.
Спецификация пакета
Если не указано иное, передача аргумента null конструктору или методу любого класса или интерфейса в этом пакете приводит к выбрасыванию исключения NullPointerException. Поведение при передаче null кратко описывается в документации Javadoc с помощью определения "@param". Исключение "@throws NullPointerException" явно не документируется в каждом методе.
Во всех вычислениях следует проверять переполнение числовых значений и выбрасывать либо ArithmeticException, либо DateTimeException.
Замечания по проектированию (не нормативные)
API разработан так, чтобы отклонять null на раннем этапе и четко определять такое поведение. Важное исключение — методы, принимающие объект и возвращающие логическое значение для проверки или подтверждения корректности: обычно для null они возвращают false.
API разработан с учетом безопасности типов там, где это целесообразно в основном высокоуровневом API. Поэтому для отдельных понятий даты, времени и даты со временем предусмотрены разные классы, а также варианты со смещением и часовым поясом. Классов может показаться много, но для начала большинству приложений достаточно пяти типов даты и времени.
-
Instant— отметка времени -
LocalDate— дата без времени и без ссылки на смещение или часовой пояс -
LocalTime— время без даты и без ссылки на смещение или часовой пояс -
LocalDateTime— объединяет дату и время, но не содержит смещения или часового пояса -
ZonedDateTime— «полная» дата и время с часовым поясом и разрешенным смещением от UTC/Гринвича
Instant — ближайший эквивалент класса java.util.Date. ZonedDateTime — ближайший эквивалент класса java.util.GregorianCalendar.
По возможности приложениям следует использовать LocalDate, LocalTime и LocalDateTime для более точного моделирования предметной области. Например, день рождения следует хранить в коде LocalDate. Помните, что использование любого часового пояса, например 'Europe/Paris', значительно усложняет вычисления. Многие приложения можно написать, используя только LocalDate, LocalTime и Instant, добавляя часовой пояс на уровне пользовательского интерфейса (UI).
Типы даты и времени со смещением OffsetTime и OffsetDateTime предназначены главным образом для работы с сетевыми протоколами и базами данных. Например, большинство баз данных не могут автоматически сохранять часовой пояс, такой как 'Europe/Paris', но могут сохранять смещение, например '+02:00'.
Также предусмотрены классы для наиболее важных частей даты, включая Month, DayOfWeek, Year, YearMonth и MonthDay. Их можно использовать для моделирования более сложных понятий даты и времени. Например, YearMonth удобно использовать для представления срока действия кредитной карты.
Обратите внимание: несмотря на большое количество классов, представляющих различные аспекты дат, классов для различных аспектов времени сравнительно мало. Последовательное применение принципа безопасности типов привело бы к созданию классов для часов и минут, часов, минут и секунд, а также часов, минут, секунд и наносекунд. Логически такой подход безупречен, но практически неприемлем, поскольку число классов почти утроилось бы из-за сочетаний даты и времени. Поэтому LocalTime используется для любой точности времени, а нули обозначают меньшую точность.
Доведение принципа безопасности типов до логического предела могло бы также привести к созданию отдельного класса для каждого поля даты и времени, например класса для часа суток и другого — для дня месяца. Такой подход был опробован, но оказался чрезмерно сложным и неудобным для использования в языке Java. Аналогичная проблема возникает с периодами. Можно было бы создать отдельный класс для каждой единицы периода, например тип для лет и тип для минут. Однако это привело бы к появлению множества классов и проблеме преобразования типов. Таким образом, набор предоставляемых типов даты и времени представляет собой компромисс между строгостью и практичностью.
API имеет относительно большую поверхность с точки зрения количества методов. Управлять этим многообразием помогает последовательное использование префиксов методов.
-
of— статический фабричный метод -
parse— статический фабричный метод, предназначенный для разбора -
get— получает значение чего-либо -
is— проверяет, истинно ли условие -
with— неизменяемый эквивалент сеттера -
plus— добавляет величину к объекту -
minus— вычитает величину из объекта -
to— преобразует этот объект в другой тип -
at— объединяет этот объект с другим, напримерdate.atTime(time)
Поддержка нескольких календарных систем представляет собой непростую дополнительную задачу проектирования. Первый принцип заключается в том, что большинству пользователей нужна стандартная календарная система ISO. Поэтому основные классы поддерживают только ISO. Второй принцип заключается в том, что большинству пользователей, которым нужна календарная система, отличная от ISO, она требуется для взаимодействия с пользователем, то есть это задача локализации пользовательского интерфейса. Поэтому объекты даты и времени должны храниться в модели данных и постоянном хранилище как объекты ISO и преобразовываться в локальный календарь и обратно только для отображения. Календарную систему следует хранить отдельно в настройках пользователя.
Однако существуют ограниченные сценарии, в которых пользователи считают необходимым хранить даты в произвольных календарных системах и использовать их во всем приложении. Такая возможность поддерживается интерфейсом ChronoLocalDate, однако перед его использованием крайне важно ознакомиться со всеми соответствующими предупреждениями в документации Javadoc этого интерфейса. Вкратце: приложениям, которым требуется общее взаимодействие между несколькими календарными системами, обычно нужна архитектура, существенно отличающаяся от архитектуры приложений, использующих только календарь ISO. Поэтому большинству приложений следует использовать только ISO и избегать ChronoLocalDate.
API также разработан с учетом возможности расширения пользователями, поскольку способы вычисления времени могут быть различными. API полей и единиц, доступный через TemporalAccessor и Temporal, предоставляет приложениям значительную гибкость. Кроме того, интерфейсы TemporalQuery и TemporalAdjuster предоставляют широкие возможности для повседневной работы, позволяя писать код, близкий к требованиям бизнеса:
LocalDate customerBirthday = customer.loadBirthdayFromDatabase();
LocalDate today = LocalDate.now();
if (customerBirthday.equals(today)) {
LocalDate specialOfferExpiryDate = today.plusWeeks(2).with(next(FRIDAY));
customer.sendBirthdaySpecialOffer(specialOfferExpiryDate);
}
- Начиная с версии:
- 1.8
| Класс | Описание |
|---|---|
| Clock | Часы, предоставляющие доступ к текущему моменту, дате и времени с использованием часового пояса. |
| DateTimeException | Исключение, указывающее на проблему при вычислении даты и времени. |
| DayOfWeek | День недели, например 'Tuesday'. |
| Duration | Величина времени, например '34.5 seconds'. |
| Instant | Мгновенная точка на временной шкале. |
| InstantSource | Предоставляет доступ к текущему моменту времени. |
| LocalDate | Дата без часового пояса в календарной системе ISO-8601, например 2007-12-03. |
| LocalDateTime | Дата и время без часового пояса в календарной системе ISO-8601, например 2007-12-03T10:15:30. |
| LocalTime | Время без часового пояса в календарной системе ISO-8601, например 10:15:30. |
| Month | Месяц года, например 'July'. |
| MonthDay | Месяц и день в календарной системе ISO-8601, например --12-03. |
| OffsetDateTime | Дата и время со смещением от UTC/Гринвича в календарной системе ISO-8601, например 2007-12-03T10:15:30+01:00. |
| OffsetTime | Время со смещением от UTC/Гринвича в календарной системе ISO-8601, например 10:15:30+01:00. |
| Period | Величина времени, определяемая датой, в календарной системе ISO-8601, например '2 years, 3 months and 4 days'. |
| Year | Год в календарной системе ISO-8601, например 2007. |
| YearMonth | Год и месяц в календарной системе ISO-8601, например 2007-12. |
| ZonedDateTime | Дата и время с часовым поясом в календарной системе ISO-8601, например 2007-12-03T10:15:30+01:00 Europe/Paris. |
| ZoneId | Идентификатор часового пояса, например Europe/Paris. |
| ZoneOffset | Смещение часового пояса относительно Гринвича/UTC, например +02:00. |
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/package-summary.html