JavaRush /Курси /Java Syntax Zero /Відображення часу — форматування

Відображення часу — форматування

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

1. Клас DateTimeFormatter

У Date Time API було додано спеціальний клас DateTimeFormatter. Його призначення — максимально полегшити перетворення дати й часу саме в той формат, який потрібен програмісту. І можна сказати, що авторам Java це вдалося.

Користуватися цим класом дуже просто. Спочатку потрібно створити об'єкт класу DateTimeFormatter і передати в нього шаблон, за яким відображатимуться дата й час:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern(шаблон);

де dtf — це змінна типу DateTimeFormatter, DateTimeFormatter.ofPattern() — це статичний метод класу DateTimeFormatter, а шаблон — це рядок, що задає шаблон, за яким відображатимуться дата й час.

Приклади

Код Виведення на екран
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-yy");
String text = dtf.format( LocalDateTime.now() );
System.out.println(text);


02-22-19

У прикладі вище ми за допомогою методу ofPattern() створюємо об'єкт DateTimeFormatter на основі рядка-шаблону. А в наступному рядку за допомогою методу format() перетворюємо об'єкт типу LocalDateTime на рядок. Результат ви бачите на екрані.

У метод format() можна передати практично будь-який об'єкт із Date Time API.

Статичний метод ofPattern() теж дуже простий: отримує як параметр рядок-шаблон, а повертає об'єкт типу DateTimeFormatter. Найцікавіше міститься всередині шаблону.


2. Шаблон форматування

Рядок, переданий параметром, використовується як шаблон під час виведення інформації. MM замінюється на номер місяця, dd — на день місяця, yy — на номер року. Регістр літер має значення.

Повна таблиця перетворення часу має такий вигляд:

Літера Позначення
y Рік (Year)
M Місяць (Month)
d День (day)
H Години (Hours)
m Хвилини (Minutes)
s Секунди (Seconds)
S Мілісекунди
n Наносекунди

Взагалі, запам'ятати не складно.

А чому тоді в шаблоні з прикладу літери MM, dd та yy написані по два рази? А це вже цікавіше.

Загальна ідея

Кількість літер впливає на довжину тексту. Що більше літер, то довшим буде текст.

Якщо літеру H вказано один раз, то 9 година відображатиметься як 9, а якщо літеру H указано двічі поспіль, то 9 година відображатиметься як 09.

Якщо літеру y вказано двічі поспіль, то рік пишеться 2 цифрами, якщо 4 рази поспіль — 4-мя цифрами.

Якщо літеру M вказано двічі поспіль, то пишеться номер місяця, якщо тричі поспіль, то назва місяця (3 перші літери), якщо 4 рази поспіль, то повна назва місяця.

Приклад:

Код Виведення на екран
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMMM-dd-yyyy");
String text = dtf.format( LocalDateTime.now() );
System.out.println(text);


February-22-2019


3. Повна таблиця шаблонів

Повна таблиця досить велика й дуже цікава:

Шаблон Варіанти шаблону Приклад Опис
y yy, yyyy 19; 2019 Рік
M/L M, MM, MMM, MMMM, MMMMM 1; 01; Jan; January; J Місяць
d d, dd 9; 09 День
H H, HH 2; 02 Години
m m, mm 3; 03 Хвилини
s s, ss 5; 05 Секунди
S S, SS, SSS, ... 1; 12; 123 Мілісекунди
n n 123456789 Наносекунди
G G, GGGG, GGGGG AD; Anno Domini; A; Ера
Q/q q, qq, qqq, qqqq 3; 03; Q3; 3rd quarter Квартал
w w 13 Тиждень року
W W 3 Тиждень місяця
E EEE, EEEE, EEEEE Mon; Monday; M День тижня
e/c e, ee, eee, eeee, eeeee 1; 01; Mon; Monday; M День тижня
a a PM AM або PM
h h 12 Час 1–12 годин
V VV Europe/Helsinki Часова зона
z z zzzz EET;  Eastern European Standard Time Часова зона
O O OOOO GMT+2;  GMT+02:00 Часова зона

Це, до речі, ще неповний список. Повний знаходиться за посиланням:

https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/time/format/DateTimeFormatter.html



4. Парсинг часу

Клас DateTimeFormatter цікавий ще й тим, що може не тільки перетворювати дату й час на рядок за заданим шаблоном, але й виконувати зворотну операцію!

Аналіз і розбір рядка називають парсингом, від слова parse.

Отакий вигляд має цей процес:

Код Виведення на екран
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMMM-dd-yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse("February-23-2019", dtf);
System.out.println(date);


2019-02-23

Спочатку ми створюємо об'єкт DateTimeFormatter і задаємо в ньому шаблон парсингу.

Відтак викликаємо метод LocalDate.parse() або LocalTime.parse(), або LocalDateTime.parse() і передаємо в цей метод рядок, який потрібно розпарсити, і об'єкт DateTimeFormatter, який розуміє, як і за яким шаблоном слід розпарсити переданий текст.

Ще один приклад: цього разу з парсингом часу.

Код Виведення на екран
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalTime time = LocalTime.parse("23:59:59", dtf);
System.out.println(time);


23:59:59

Коментарі (8)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
1 квітня 2025
І хто б в лекціі написав, що в шаблоний рядок можна вставляти ліві літери, і вони будуть відображатися?🤦‍♂️ Я ніколи в житті б не здогадався, що можна ость так "dd.MM.yyyyр. Hг.mхв" написати, був впевненний, що якщо буде хоч якась зайва літера поза формату шаблона - обов'язково буде помилка
IronMan57 Рівень 28
15 січня 2025
Незрозуміло, чому при використанні в останній задачі в шаблоні для визначення року "YYYY" замість "yyyy" викидає виняток. Обидва рядки позначають рік. Здається, навіть зрозумів різницю між цими роками, код компілюється, але чому викидається виняток при парсингу не ясно.
Jaroslav Рівень 48
19 січня 2025
Наче допускається лише мала літера
IronMan57 Рівень 28
20 січня 2025
В документації (починаючи з 11-ї версії, точно - Class DateTimeFormatter) вказані і малі, і великі літери. Малі літери задають шаблон для "year-of-era", а великі для "week-based-year". В останньому варіанті, наскільки я зрозумів, можуть бути особливості з входженням кількох перших або останніх днів календарного року в інший рік.
Neridnyi Taras Рівень 23
29 листопада 2022
Задача "Простий шаблон" Вирішив майже так само . Вивід той самий і в Eclipse все працює задовільно. Але тут валідатор вказує на те , що я не виконав умов Завдання .
Beisik Рівень 25
14 січня 2023
пробіл між місяцем і часом поставили ?
Grimnir Рівень 10
19 січня 2023
З третьої спроби тільки точно все прописав... Зате другу задачу після цієї вже всі уважно прописують, судячи з кількості вдалих спроб:)
Serhii #2958832 Рівень 51 Expert
10 червня 2023
Кілька невдалих спроб, а потім пропустило. Думаю проблема була через "р" - рік, в англійській розкладці. Знову "Н" - неуважність)))