JavaRush /Курси /Java Syntax Zero /Часові пояси

Часові пояси

Java Syntax Zero
Рівень 17 , Лекція 7
Відкрита

1. Клас ZonedDateTime

Є ще один дуже цікавий клас в Date Time API — клас ZonedDateTime. Основне його призначення — зручно працювати з датами в різних часових поясах.

LocalDate ідеально підходить для опису дат. Наприклад, дня народження: у мене день народження 15 березня незалежно від того, де я знаходжусь. Це приклад дати.

LocalTime ідеально підходить для опису часу, наприклад, будильника: я завів будильник на 5 ранку і байдуже, де я знаходжусь. 5 ранку — це 5 ранку. Це приклад роботи з часом.

А тепер припустимо, що ми пишемо застосунок, який бронює авіаквитки. Літаки злітають і приземляються за місцевим часом, літак летить фіксований час, але часові пояси змінюються.

Часові зони

До речі, з часовими зонами у світі справжній хаос. Більше того, якщо ви думаєте, що часових поясів 24, ви серйозно помиляєтесь.

Наприклад, час в Індії відрізняється від Грінвіча на 5 з половиною годин: GMT+5:30. Одні країни переходять на літній час, інші ні. Причому різні країни переходять на літній час в різний час року.

А деякі країни за допомогою законів скасовують перехід на літній час, або знову вводять, або знову скасовують.

Загалом, у світі є часові зони, всередині кожної зони один і той самий час. Час в різних зонах може збігатись в певні періоди року, а в інші періоди відрізнятись. Зони зазвичай називають за великими містами, що знаходяться в них: Europe/Monaco, Asia/Singapore, хоча бувають і винятки — US/Pacific.

Загалом на даний момент офіційно відомо 599 часових зон. Уявіть собі: 599. Це зовсім не 24. Ласкаво просимо до глобального світу.

Для зберігання часової зони в Java використовується клас ZoneId з пакету java.time.

До речі, у нього є статичний метод getAvailableZoneIds(), який повертає множину всіх відомих на поточний момент часових зон. Щоб отримати список всіх зон, потрібно написати такий код:

Код Вивід на екран (частина)
for (String s: ZoneId.getAvailableZoneIds())
   System.out.println(s);
Asia/Aden
America/Cuiaba
Etc/GMT+9
Etc/GMT+8

Щоб отримати об'єкт ZoneId за його ім’ям, потрібно скористатися статичним методом of();

Код Примітка
ZoneId zone = ZoneId.of("Africa/Cairo");
Каїр


2. Створення об'єкта ZonedDateTime

При створенні об'єкта ZonedDateTime потрібно викликати у нього статичний метод now() і передати до нього об'єкт ZoneId.

Код Вивід на екран
ZoneId zone = ZoneId.of("Africa/Cairo");
ZonedDateTime time = ZonedDateTime.now(zone);
System.out.println(time);


2019-02-22T11:37:58.074816+02:00[Africa/Cairo]

Якщо до методу now() не передати об'єкт ZoneId, а так можна, часова зона буде визначена автоматично: на основі налаштувань комп'ютера, на якому виконується програма.

Приклад:

Код Вивід на екран
ZonedDateTime time = ZonedDateTime.now();
System.out.println(time);

2019-02-22T13:39:05.70842+02:00[Europe/Helsinki]

Перетворення глобальної дати в локальну

Однією з цікавих особливостей 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 є багато способів отримати окремі фрагменти дати і часу. Ось список цих методів:

int getYear()
Повертає рік з конкретної дати
Month getMonth()
Повертає місяць дати: одну зі спеціальних констант JANUARY, FEBRUARY, ...;
int getMonthValue()
Повертає номер місяця з дати. Січень == 1
int getDayOfMonth()
Повертає номер дня в місяці
DayOfWeek getDayOfWeek()
Повертає день тижня: одну зі спеціальних констант MONDAY, TUESDAY, ...;
int getDayOfYear()
Повертає номер дня в році
int getHour()
Повертає години
int getMinute()
Повертає хвилини
int getSecond()
Повертає секунди
int getNano()
Повертає наносекунди

Усі методи повністю аналогічні методам LocalDateTime. І, звісно, у класу ZonedDateTime є методи, які дозволяють працювати з датою та часом. При цьому об'єкт, у якого викликаються методи, не змінюється: замість цього методи повертають новий об'єкт ZonedDateTime:

Методи Опис
plusYears(int)
Додає роки до дати
plusMonths(int)
Додає місяці до дати
plusDays(int)
Додає дні до дати
plusHours(int)
Додає години
plusMinutes(int)
Додає хвилини
plusSeconds(int)
Додає секунди
plusNanos(int)
Додає наносекунди
minusYears(int)
Віднімає роки від дати
minusMonths(int)
Віднімає місяці від дати
minusDays(int)
Віднімає дні від дати
minusHours(int)
Віднімає години
minusMinutes(int)
Віднімає хвилини
minusSeconds(int)
Віднімає секунди
minusNanos(int)
Віднімає наносекунди

Приклади наводити не будемо: думаємо, тут і так все зрозуміло за аналогією з тільки що розглянутими класами.


Коментарі (15)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Aleksey Golovin Рівень 48
1 жовтня 2025
LocalDateTime localDateTime = cairoTime.toLocalDateTime(); !! це не поретворює час десь там на час на вашій машині, це лише відкидає зону, залишаючи час без змін. для цього потрібен метод withZoneSameInstant(toZone); toZone - це часова зона в які ви хочете отримати час
Aleksey Golovin Рівень 48
1 жовтня 2025
"А деякі країни міняють закони і скасовують перехід на літній час або знову вводять, або знову скасовують." І шо то за країни такі? ))
Кирило Рівень 43
24 серпня 2024
Це, насправді, круто що джавараш заставляє нас читати документацію, бо якщо розкладувати всі методи і статичні змінні в лекціях, то виділити найважливіше з них буде нереально, погано інше, те що постійно виникає проблема нерозуміння що робити з кодом, треба використовувати якісь вивчені метод, чи це можно зробити тільки не вивченими.
Olexandr Рівень 47
29 січня 2024
Останню задачу розв'язав майже легко. Ну як розв'язав, Chat GPT все придумав а я вже допиляв під валідатор. Можу сказати одне - то саме пресловуте гуглення для пошуку рішення - перетворилося на спитай ChatGpt та адаптуй відповідь під себе... Не знаю добре це чи ні, і куди це все йде...
Андрій Рівень 18
8 травня 2024
Те саме)
TimpoIngo Рівень 38
11 вересня 2023
Ви теж пишете багато рядків, а потім дивуєтеся наскільки можна було просто написати?🤭
Андрии Бумер Рівень 37
19 вересня 2024
О так)
unite Рівень 24 Expert
8 лютого 2023
навіть напрямок вирішення останньої задачі не вказанив в лекції де шукати withZoneSameInstant? . Так і не зрозумів чому знаючи час мі не можемо одразу визначити його в зоні 2? навіщо зона 1 ?
kalkulator¹ Рівень 51
24 листопада 2022
я зрозумів, що в коментах ніколи не побачу людину з левелом нижче ніж в мене(якщо не вертатися назад звісно)
Bandiu Band Рівень 25
27 вересня 2022
Методи atZone(ZoneId); withZoneSameInstant(ZoneId);
FAUST_ua Рівень 29
26 вересня 2022
Перша задача має бути після частини 2 лекції.
Pavlo Kezin Рівень 23
26 вересня 2023
приєднуюсь
Андрии Бумер Рівень 37
19 вересня 2024
аххах, мені сподобалось таке рішення. Я випадково прочитав другу частину і одразу побачив там відповідь на перше завдання, пощастило. Уже майже напрацьована звичка: якщо одразу не розумієш як зробити, то перед тим як гуглити почитай лекцію далі) яцщо і там рішення нема, тоді впередю Хоча з TreeSet одразу з завдання стало зрозуміло що читати треба саме його))
18 липня 2022
Як завжди методи необхідні для вирішення задачі у лекції не вказані. Мабуть це тренування на головний скіл програміста - пошук...
Roman Рівень 20 Expert
4 серпня 2022
Так, але це ж добре)