Нарешті Java з'явився інтуїтивний, надійний метод роботи з датами і часом. Принципи дати та часу є фундаментальними у багатьох додатках. Такі різні речі як дати народження, терміни оренди, час подій та години відкриття магазину, всі засновані на датах та часі, але Java SE не надавала зручного способу роботи з ними. Починаючи з Java SE 8 з'явився набір пакетів java.time - який надає добре структурований API для роботи з датами та часом.
Ось невеликий список наявних проблем у його реалізації:
Передісторія
Коли Java вперше з'явилася, у версії 1.0 єдиним класом для роботи з датами і часом був java.util.Date . Першим на що звернули увагу розробники було те, що він не є «датою». Насправді він є моментом часу з точністю до мілісекунд, відміряний з дати 1-го січня 1970-го року. Однак, на підставі того, що метод toString() у Date виводить дату і час у тому часовому поясі, який зазначений в налаштуваннях java машини, деякі розробники помилково зробабо висновок про те, що Date вміє працювати з часовими поясами. Виправити цей клас виявилося настільки складно (або настільки ліниво) що у версії 1.1 довелося додати новий клас - java.util.Calendar . На жаль, клас Calendar виявився не сильно кращим ніж Date .- Змінюваний. Такі класи як дата і час мають бути незмінними.
- Зміщення. Роки в Date починаються з 1900 року, місяці в обох класах починаються з нуля.
- Найменування. Date це насправді не дата, і Calendar не є календарем.
- Форматування. Форматування працює тільки з Date, а не з Calendar і не є потокобезпечним.
Огляд
Новий API java.time містить 5 пакетів:- java.time - базовий пакет, що містить об'єкти для зберігання значень
- java.time.chrono - надає доступ до різних календарів
- java.time.format - форматування та розпізнавання дати та часу
- java.time.temporal - низькорівневі бібліотеки та розширений функціонал
- java.time.zone - класи для роботи з часовими поясами
Дати
Клас LocalDate - один із найголовніших у новому API . Він містить незмінне значення, що є датою. Не можна встановити час або часовий пояс. Назва «local» вам може бути знайома з Joda-Time , і спочатку походить зі стандарту ISO-8601 . Воно означає саме відсутність часового поясу. По суті, LocalDate це опис дати, таке як "5 квітня 2014". Фактичний час цієї дати буде відрізнятися, залежно від вашого часового поясу. Наприклад, в Австралії ця дата буде на 10 годин раніше, ніж у Лондоні, і на 18 годин раніше, ніж у Сан Франциско. У класі LocalDate є всі потрібні методи:LocalDate date = LocalDate.of(2014, Month.JUNE, 10); int year = date.getYear(); // 2014 Month month = date.getMonth(); // Июнь int dom = date.getDayOfMonth(); // 10 DayOfWeek dow = date.getDayOfWeek(); // Вторник int len = date.lengthOfMonth(); // 30 (дней в Июне) boolean leap = date.isLeapYear(); // false (не високосный год)
У нашому прикладі, бачимо дату створену з допомогою метода-фабрики (всі конструктори приватні). Далі ми запитуємо деякі дані у об'єкта. Зверніть увагу, що перерахування
Month та
DayOfWeek створені для того, щоб робити код більш читаним та надійним. У наступному прикладі ми побачимо, як модифікувати дату. Так як клас незмінний, результатом будуть нові об'єкти, а вихідний залишиться як був.
LocalDate date = LocalDate.of(2014, Month.JUNE, 10); date = date.withYear(2015); // 2015-06-10 date = date.plusMonths(2); // 2015-08-10 date = date.minusDays(1); // 2015-08-09
Це відносно прості зміни, але часто вам потрібно зробити складніші модифікації дати. Для цього існує спеціальний механізм в
java.time API-TemporalAdjuster . Його мета - надати вбудований інструмент, що дозволяє маніпулювати датами, наприклад отримати об'єкт, що відповідає останньому дню місяця. Деякі з них входять до складу
API , але ви можете додавати свої власні. Використовувати модифікатори дуже просто, але для цього потрібні статичні імпорти:
import static java.time.DayOfWeek.* import static java.time.temporal.TemporalAdjusters.* LocalDate date = LocalDate.of(2014, Month.JUNE, 10); date = date.with(lastDayOfMonth()); date = date.with(nextOrSame(WEDNESDAY));
Використання модифікаторів дуже спрощує ваш код. Нікому не хочеться бачити велику кількість маніпуляцій із датою вручну. Якщо якась маніпуляція з датою зустрічається у вашому проекті кілька разів, напишіть власний модифікатор, і ваша команда зможе скористатися ним як уже написаним і протестованим компонентом.