JavaRush/Java блог/Random UA/Інтуїтивно зрозуміла, надійна бібліотека для роботи з час...
theGrass
24 рівень

Інтуїтивно зрозуміла, надійна бібліотека для роботи з часом і датами, з'явилася в Java (Частина 2).

Стаття з групи Random UA
учасників
Час доби
    Отже, йдемо далі. Наступною сутністю після дати є час доби, що представляється класом LocalTime . Класичний приклад – представлення часу роботи магазину, скажімо з 7:00 до 23:00. Магазини відкриваються в цей час по всій країні, але фактичний час буде різним, залежно від часового поясу.     LocalTime це клас-значення, в якому зберігається лише час, без асоційованої дати та часового поясу. При додаванні або відніманні часового проміжку, він обріжеться по півночі. Тобто 20:00 плюс 6 годин це 2:00. Використання LocalTime схоже на LocalDate : LocalTime time = LocalTime.of(20, 30); int hour = date.getHour(); // 20 int minute = date.getMinute(); // 30 time = time.withSecond(6); // 20:30:06 time = time.plusMinutes(3); // 20:33:06     Модифікатори можуть працювати і з LocalTime , проте операції з часом зазвичай не настільки складні, щоб потрібно використання модифікаторів.
Комбінування дати та часу
    Наступний клас який ми розглянемо - LocalDateTime . Цей клас-значення є комбінацією LocalDate та LocalTime . Він представляє і дату, і час, без часового поясу.      LocalDateTime може бути створений або безпосередньо або комбінуючи дату і час: LocalDateTime dt1 = LocalDateTime.of(2014, Month.JUNE, 10, 20, 30); LocalDateTime dt2 = LocalDateTime.of(date, time); LocalDateTime dt3 = date.atTime(20, 30); LocalDateTime dt4 = date.atTime(time);     Третій і четвертий варіанти використовують метод atTime() , який надає гнучкий спосіб комбінувати дату і час. Більшість системних класів дати та часу мають «at» методи, які можуть бути використані при комбінуванні вашого об'єкта з іншим, щоб створити більш складний. Інші методи класу LocalDateTime схожі на аналогічні з LocalDate та LocalTime . Подібні шаблони найменування методів допомагають легше вивчити API . У цій таблиці перелічені всі задіяні префікси методів: Інтуїтивно зрозуміла, надійна бібліотека для роботи з часом і датами, з'явилася в Java (Частина 2).  - 1
Instant
    Коли ми маємо справу з датами та часом, зазвичай ми працюємо з роками, місяцями, днями, годинами, хвабонами, секундами. Однак це лише одна модель часу, яку можна назвати «людська». Друга модель, що часто використовується, - «машинного» або «безперервного» часу. У цій моделі точка на осі часу представлена ​​одним великим числом. Даний підхід спрощує алгоритми розрахунку, і використовується для зберігання часу в операційній системі Unix , там час представлений числом секунд, що пройшли з 1 січня 1970 року. Аналогічно, в Java час зберігається як число мілісекунд минулих з 1 січня 1970 року. Машинний підхід до розрахунків часу в java.time API забезпечується класом-значенням Instant . Він надає можливість подати крапку на осі часу без усієї супутньої інформації, такої як часовий пояс. Фактично, цей клас містить у собі число наносекунд, що пройшло з півночі 1 січня 1970 року. Instant start = Instant.now(); // произведем вычисления Instant end = Instant.now(); assert end.isAfter(start); //машина времени не сработала     Зазвичай клас Instant використовується для зберігання та порівняння моментів часу, коли вам потрібно зберегти коли трапилася якась подія, але вас не хвилює часовий пояс у якому це сталося. У більшості випадків, цікавіше те, чого ми не можемо зробити з класом Instant ніж те, що ми зможемо з ним зробити. Наприклад, такі рядки коду викличуть винятки: instant.get(ChronoField.MONTH_OF_YEAR); instant.plus(6, ChronoUnit.YEARS);     Винятки відбуваються оскільки об'єкт instant зберігає лише кількість наносекунд і дозволяє працювати з одиницями часу кориснішими людині. Для того, щоб скористатися іншими одиницями вимірювання, вам як мінімум потрібно вказати часовий пояс.
Часові пояси
    Принцип часових поясів був розроблений в Англії, коли винахід залізниць та покращення інших способів зв'язку дозволило людям переміщатися на відстані, достатні для того, щоб різниця в сонячному часі була помітною. До цього часу, кожне село та місто жабо за своїм часом, який найчастіше вимірювали за сонячним годинником. На цій картинці видно приклад того, до яких складнощів це призводило - червоні стрілки на годиннику показують час за Грінвічем, а чорна - місцевий час, що відрізняється на 10 хвабон: Система часових поясів розвивалася, замінюючи собою локальний сонячний час Інтуїтивно зрозуміла, надійна бібліотека для роботи з часом і датами, з'явилася в Java (Частина 2).  - 2     . Але ключовий факт – часові пояси створені політиками, і часто використовуються, щоб демонструвати політичний контроль над територією. Як і будь-яка політика, правила пов'язані з часовими поясами часто суперечать логіці. А також ці правила можуть змінюватися, і часто змінюються, без жодних попереджень. Правила часових поясів зібрані міжнародною групою, яка опублікувала базу часових поясів IANA . Там міститься ідентифікатор кожного регіону Землі та історія змін часових поясів для нього. Ідентифікатори виглядають як “Europe/London” або “America/New_York” . До виходу java.time API для подання часового поясу використовувався клас TimeZone . Тепер замість нього використовується ZoneId . Між ними є дві ключові відмінності. Перше - ZoneId є незмінним, що дає можливість зберігати об'єкти цього класу в статичних змінних серед усього іншого. Друге - самі правила зберігаються в класі ZoneRules , а не в самому ZoneId , і щоб отримати їх, потрібно викликати метод getRules() у об'єкта класу ZoneId . Загальною рисою всіх часових поясів є фіксоване зміщення від UTC/Greenwich . Найчастіше ви використовуєте це, коли кажете про різницю в часі між різними містами, такими як Нью Йорк на 5 годин відстає від Лондона. Клас ZoneOffset , що є спадкоємцем ZoneId , представляє різницю в часі з нульовим мерідіаном, що проходить через Грінвіч у Лондоні. З погляду розробника, було б добре не поратися з часовими поясами та їх складнощами. java.time API дозволяє вам робити це до тих пір, поки це в принципі можливо. Скрізь де є можливість, використовуйте класи LocalDate, LocalTime, LocalDateTime та Instant . Там же, де без часових поясів не можна, використовуйте клас ZonedDateTime . Клас ZonedDateTimeдозволяє перетворювати дати та час з людських одиниць виміру, які ми бачимо на календарях та годинах, на машинні одиниці. Як наслідок, створити ZonedTimeDate ви можете як з Local класу, так і Instant : ZoneId zone = ZoneId.of("Europe/Paris"); LocalDate date = LocalDate.of(2014, Month.JUNE, 10); ZonedDateTime zdt1 = date.atStartOfDay(zone); Instant instant = Instant.now(); ZonedDateTime zdt2 = instant.atZone(zone);     Однією з найнеприємніших особливостей часових поясів є так званий літній час. З переходом на літній час і назад різниця вашого часового поясу з Грінвічем змінюється двічі (або більше) на рік, зазвичай збільшуючись навесні і зменшуючись восени. Коли це відбувається, ми повинні перевести всі годинники у нас вдома. У класах java.time дані усунення представлені як «перетворення усунення» . Навесні це викликає «розрив» у часі, коли деякі значення часу неможливі, а восени навпаки – деякі значення часу виникають двічі. Все це підтримується класом ZonedDateTime за допомогою його методів-фабрик та методів перетворювачів. Наприклад, поповнення одного дня додає логічний день, який може бути представлений більше або менше ніж 24 годин, якщо ми переходимо на літній час або назад. Аналогічно, метод atStartOfDay() названий так тому, що ми не можемо гарантувати, що день почнеться рівно опівночі - треба враховувати розрив часу при переході на літнє. І остання підказка щодо літнього часу. Якщо ви хочете продемонструвати, що ви врахували нахлест часу при переході з літнього на зимове (коли одне і те ж значення часу виникає двічі), ви можете використовувати один із двох спеціальних методів, призначених для таких ситуацій: Дані методи повернуть більш раннє або пізніше zdt = zdt.withEarlierOffsetAtOverlap(); zdt = zdt.withLaterOffsetAtOverlap();     значення якщо об'єкт потрапив у нахлест при переході з літнього часу на зимове. У всіх інших ситуаціях значення, що повертаються, будуть однаковими.
Проміжки часу
    Усі класи, які ми обговорювали раніше, працюють точками на шкалі часу. Два додаткові класи-значення потрібні для подання проміжків часу. Клас Duration представляє відрізок часу, що вимірюється в секундах та наносекундах. Наприклад, "23.6 секунд". Клас Period представляє проміжок часу, що вимірюється в роках, місяцях та днях. Наприклад - «3 роки, 2 місяці та 6 днів». Ці проміжки можуть бути додані або відняти з дати або часу: Period sixMonths = Period.ofMonths(6); LocalDate date = LocalDate.now(); LocalDate future = date.plus(sixMonths);
Форматування та розбір
    Цілий пакет призначений для форматування та виведення дат та часу - java.time.format . Пакет обертається навколо класу DateTimeFormatter та його фабрики DateTimeFormatterBuilder . Найпоширенішими способами створення форматувальника є статичні методи та константи в DateTimeFormatter , включаючи:
  • Константи для поширених форматів описаних у ISO, таких як ISO_LOCAL_DATE.
  • Шаблони позначаються літерами, такі як ofPattern("dd/MM/uuuu").
  • Локалізовані стилі, такі як зLocalizedDate(FormatStyle.MEDIUM).
    Після того, як ви створабо форматувальник, зазвичай ви використовуєте його передавши у відповідний метод класу дати: DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/uuuu"); LocalDate date = LocalDate.parse("24/06/2014", f); String str = date.format(f);     Таким чином, код, який відповідає за форматований висновок дати, ізольований в окремий клас. Якщо вам потрібно окремо вказати локаль для форматування дати, використовуйте метод форматування withLocale(Locale) . Аналогічні методи є у класів, які відповідають за календар, часовий пояс, введення/виведення дробових чисел. Якщо вам потрібне тонше налаштування параметрів, дивіться документацію на клас DateTimeFormatterBuilder , що дозволяє створювати складні форматувальники крок за кроком. Також він дозволяє задавати реєстронезалежний розбір тексту, ігнорувати частину помилок розбору, задавати зміщення та необов'язкові елементи.
Підсумок
     java.time API - нова всеосяжна модель для роботи з датою та часом у Java SE 8 . Вона бере ідеї та реалізації з Joda-Time на наступний рівень і нарешті дозволяє розробникам не використовувати java.util.Date та Calendar . Тепер робота з датами і часом може приносити задоволення!      Оригінал статті
Коментарі
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
Для цієї сторінки немає коментарів.