1. Класс ZonedDateTime
Есть еще один очень интересный класс в Date Time API — класс ZonedDateTime
. Основное его назначение — удобно работать с датами в разных часовых поясах.
LocalDate
отлично подходит для описания дат. Например, дня рождения: у меня день рождения 15 марта независимо от того, где я нахожусь. Это пример даты.
LocalTime
отлично подходит для описания времени, например, будильника: я завел будильник на 5 утра и все равно, где я нахожусь. 5 утра — это 5 утра. Это пример работы с временем.
А теперь допустим, что мы пишем приложение, которое бронирует авиабилеты. Самолеты взлетают и прилетают по местному времени, самолет летит фиксированное время, но часовые пояса меняются.
Временные зоны
Кстати, с временными зонами (часовыми поясами) в мире настоящий бардак. Более того, если вы думаете, что часовых поясов 24, вы сильно ошибаетесь.
Например, время в Индии отличается от Гринвича на 5 c половиной часов: GMT+5:30
. Одни страны переходят на летнее время, другие нет. Причем разные страны переходят на летнее время в разное время года.
А некоторые страны с помощью законов отменяют переход на летнее время, или снова вводят, или опять отменяют.
В общем, в мире есть временные зоны, внутри каждой зоны одно время. Время в разных зонах может совпадать в определенные периоды года, а в другие периоды отличаться. Зоны обычно называют по крупным городам, находящимся в них: Europe/Monaco
, Asia/Singapore
, хотя бывают и исключения — US/Pacific
.
Всего в настоящий момент официально известно 599 временных зон. Вдумайтесь: 599. Это совсем не 24. Добро пожаловать в глобальный мир.
Для хранения временной зоны в Java используется класс ZoneId
из пакета java.time
.
Кстати, у него есть статический метод getAvailableZoneIds()
, который возвращает множество всех известных на текущий момент временных зон. Чтобы получить список всех зон, нужно написать такой код:
Код | Вывод на экран (часть) |
---|---|
|
|
Чтобы получить объект ZoneId
по его имени, нужно воспользоваться статическим методом of()
;
Код | Примечание |
---|---|
|
|
2. Создание объекта ZonedDateTime
При создании объекта ZonedDateTime
нужно вызвать у него статический метод now()
и передать в него объект ZoneId
.
Код | Вывод на экран |
---|---|
|
|
Если в метод now()
не передать объект ZoneId
, а так можно, временная зона будет определена автоматически: на основе настроек компьютера, на котором выполняется программа.
Пример:
Код | Вывод на экран |
---|---|
|
|
Преобразование глобальной даты в локальную
Одной из интересных особенностей ZonedDateTime
является возможность его преобразования в локальную дату и время. Пример.
ZoneId zone = ZoneId.of("Africa/Cairo");
ZonedDateTime cairoTime = ZonedDateTime.now(zone);
LocalDate localDate = cairoTime.toLocalDate();
LocalTime localTime = cairoTime.toLocalTime();
LocalDateTime localDateTime = cairoTime.toLocalDateTime();
3. Работа со временем
Как и у класса LocalDateTime
, у класса ZonedDateTime
есть много способов получить отдельные фрагменты даты и времени. Вот список этих методов:
|
Возвращает год из конкретной даты |
|
Возвращает месяц даты: одну из специальных констант JANUARY, FEBRUARY, ...; |
|
Возвращает номер месяца из даты. Январь == 1 |
|
Возвращает номер дня в месяце |
|
Возвращает день недели: одну из специальных констант MONDAY, TUESDAY, ...; |
|
Возвращает номер дня в году |
|
Возвращает часы |
|
Возвращает минуты |
|
Возвращает секунды |
|
Возвращает наносекунды |
Все методы полностью аналогичны методам LocalDateTime
. И, конечно, у класса ZonedDateTime
есть методы, которые позволяют работать с датой и временем. При этом объект, у которого вызываются методы, не меняется: вместо этого методы возвращают новый объект ZonedDateTime
:
Методы | Описание |
---|---|
|
Добавляет годы к дате |
|
Добавляет месяцы к дате |
|
Добавляет дни к дате |
|
Добавляет часы |
|
Добавляет минуты |
|
Добавляет секунды |
|
Добавляет наносекунды |
|
Отнимает годы от даты |
|
Отнимает месяцы от даты |
|
Отнимает дни от даты |
|
Вычитает часы |
|
Вычитает минуты |
|
Вычитает секунды |
|
Вычитает наносекунды |
Примеры приводить не будем: думаем, тут и так все понятно по аналогии с только что рассмотренными классами.