1. Введение в Date Time API
Создателям Java не сильно нравилась текущая ситуация с классами Date и Calendar. Они были хороши в свое время, но времена меняются. И нужно было что-то простое, мощное и надежное. И вот вместе с выходом Java8 (15 лет спустя после выхода Calendar
) был представлен Java Date Time API: набор классов, которые должны решить все возможные проблемы со временем.
Классов было так много, что их решили разнести по нескольким пакетам:
Пакет java.time
— базовый пакет для Java Date Time API: в нем содержатся такие классы как LocalDate
, LocalTime
, LocalDateTime
, Instant
, Period
, Duration
. Все объекты этих классов — immutable
: их нельзя изменить после создания.
Пакет java.time.format
содержит в себе классы для форматирования времени: преобразования времени (и даты) в текстовую строку и обратно. Например, в нем содержится такой универсальный класс как DateTimeFormatter
, который пришел на смену SimpleDateFormat
.
Пакет java.time.zone
содержит классы для работы с часовыми поясами (time zones). Он содержит такие классы как TimeZone
и ZonedDateTime
. Если вы пишете код для сервера, клиенты которого находятся в разных частях света, эти классы вам очень понадобятся.
2. Класс LocalDate
Первый и самый полезный класс из Date Time API, который мы изучим — это класс LocalDate
. Как вы, скорее всего, догадываетесь по его названию, этот класс создан для работы с датой.
Объекты этого класса не изменяются после создания (класс LocalDate
immutable). Зато это добавило классу простоты и надежности. Особенно если с объектом класса одновременно взаимодействуют несколько нитей (потоков исполнения).
Чтобы создать новый объект класса LocalDate
, нужно использовать один из статических методов. Вот список основных.
Получение текущей даты
Чтобы получить текущую дату, нужно воспользоваться статическим методом now()
. Это гораздо проще, чем кажется:
LocalDate today = LocalDate.now();
Где today
— это переменная класса LocalDate
, а LocalDate.now()
— вызов статического метода now()
у класса LocalDate
.
Пример:
Код | Вывод на экран |
---|---|
|
|
Получение даты в определенном часовом поясе
Также у класса LocalDate
есть разновидность метода now(ZoneId)
, который позволяет получить текущую дату в определенном часовом поясе.
Для этого нам понадобится еще один класс — ZoneId
(java.time.ZoneId). У него есть метод of()
, который возвращает объект ZoneId
по имени часового пояса.
Чтобы определить текущую дату в Шанхае, нужно написать код:
Код | Вывод на экран |
---|---|
|
|
Список имен всех часовых поясов (time zone) можно найти в интернете.
3. Получение конкретной даты
Чтобы получить объект LocalDate
, содержащий определенную дату, нужно воспользоваться статическим методом of()
. Выглядит все тоже очень просто и понятно:
LocalDate date = LocalDate.of(2019, Month.FEBRUARY, 22);
Где date
— это переменная класса LocalDate
, а LocalDate.of()
— вызов статического метода of()
у класса LocalDate
.
Также тут мы видим использование специальной константы FEBRUARY
класса Month
(java.time.Month) для задания месяца Февраль.
Можно задать месяц и по старинке — с помощью числа:
LocalDate date = LocalDate.of(2019, 2, 22);
Двойка? Вместо месяца Февраль? Это что, месяцы теперь опять нумеруются с единицы?
Да, наконец-то спустя почти 20 лет после создания Java месяцы перестали нумеровать с нуля.
Пример:
Код | Вывод на экран |
---|---|
|
|
Получение даты по номеру дня
Есть еще один любопытный метод создания даты: с помощью метода ofYearDay
можно получить дату, имея только номер года и номер дня года. Общий вид такой:
LocalDate date = LocalDate.ofYearDay(год, день);
Где год — это номер года, а день — номер дня в году.
Пример:
Код | Вывод на экран |
---|---|
|
|
Сотый день в 2019 году — это 10 апреля.
Получение даты Unix
Помните, что объекты класса Date
всегда хранили время в миллисекундах с 1 января 1970 года? Чтобы программисты не скучали по старым добрым временам, в класс LocalDate
добавили метод ofEpochDay()
, который возвращает дату, отсчитанную от 1 января 1970 года. Общий вид такой:
LocalDate date = LocalDate.ofEpochDay(день);
Где день
— это количество дней, прошедшее с 1 января 1970 года.
Пример:
Код | Вывод на экран |
---|---|
|
|
4. Получение фрагментов даты
Изменять объекты класса LocalDate
нельзя, а вот получать отдельные фрагменты даты еще как можно. Для этого у объектов класса LocalDate
есть несколько методов:
Метод | Описание |
---|---|
|
Возвращает год из конкретной даты |
|
Возвращает месяц даты — одну из специальных константJANUARY, FEBRUARY, ...; |
|
Возвращает номер месяца из даты. Январь == 1. |
|
Возвращает номер дня в месяце |
|
Возвращает номер дня с начала года |
|
Возвращает день недели: одну из специальных константMONDAY, TUESDAY, ...;
|
|
Возвращает эру: константа BC (Before Current Era) и CE (Current Era) |
Пример:
Код | Вывод на экран |
---|---|
|
|
5. Изменение даты в объекте LocalDate
Класс LocalDate
содержит несколько методов, которые позволяют работать с датой. Эти методы реализованы по аналогии с методами класса String
: каждый из этих методов не меняет существующий объект LocalDate, а возвращает новый с нужными данными.
Вот какие методы есть у класса LocalDate
:
Метод | Описание |
---|---|
|
Добавляет определенное количество дней к дате |
|
Добавляет недели к дате |
|
Добавляет месяцы к дате |
|
Добавляет годы к дате |
|
Отнимает дни от даты |
|
Отнимает недели от даты |
|
Отнимает месяцы от даты |
|
Отнимает годы от даты |
Пример:
Код | Вывод на экран |
---|---|
|
|
Объект birthday
, чьи методы мы вызываем, не меняется. Вместо этого его методы возвращают новые объекты, которые и содержат нужные данные.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ