Вступление
Java предоставляет обширный API для обработки даты и времени. В этой
статье мы будем использовать Java DateTimeFormatter для форматирования
дат - LocalDate
, LocalDatetime
, LocalTime
и ZonedDateTime
.
Перед форматированием дат вам нужно знать, как получить текущую дату и время в Java .
Спецификаторы формата
Спецификаторы формата даты и времени используются для построения шаблонов для представления данных в формате, в котором мы хотели бы их представить.
В реальном мире некоторые компоненты даты или времени часто представлены более чем одним способом. Когда дело доходит до спецификаторов формата времени и даты в Java, эти компоненты также имеют два или более представлений - иногда удобно использовать короткую версию, в то время как более длинные версии более краткие и официальные.
DateTimeFormatter
Java 8 полностью переработала API даты и времени, добавив
поточно-ориентированные классы, которые заменили старые и неуклюжие
классы Date
и Calendar
Это также познакомило нас с DateTimeFormatter
, в отличие от
SimpleDateFormat
из старого API.
Стоит отметить, что LocalDate
и LocalTime
хранят информацию только
LocalDateTime
хранит информацию как о дате, так и о времени в одном
объекте.
Есть два способа создания экземпляра DateTimeFormatter
:
Написание выкройки:
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("EEE, MMM dd. yyyy.");
Используя форматтер:
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
Используя статический метод:
1. DateTimeFormatter.ofLocalizedDate (FormatStyle dateStyle)
2. DateTimeFormatter.ofLocalizedTime (FormatStyle timeStyle)
3. DateTimeFormatter.ofLocalizedDateTime (FormatStyle datetimeStyle)
4. DateTimeFormatter.ofLocalizedDateTime (FormatStyle dateStyle,
FormatStyle timeStyle)
Например, мы могли бы настроить DateTimeFormatter
с помощью:
DateTimeFormatter formatter = DateTimeFormatter
.ofLocalizedTime(FormatStyle.SHORT);
Обратите внимание, что у каждого из них есть обязательный аргумент.
FormatStyle
- это встроенное перечисление, которое предоставляет
несколько значений - FULL
, LONG
, MEDIUM
и SHORT
.
Как доступные шаблоны перечисления выглядят при применении к
ZonedDateTime
показано в следующей таблице:
FormatStyle Описание Стиль даты Стиль времени Стиль даты и времени ПОЛНЫЙ Очень подробный Четверг, 13 августа 2020 г. 00:43:00 Центральноевропейское летнее время Четверг, 13 августа 2020 г., 00:43:48 Центральноевропейское летнее время ДЛИННЫЙ Содержит большую часть деталей 13 августа 2020 г. 00:45:27 CEST 13 августа 2020 г., 00:44:40 CEST СРЕДНЯЯ Некоторые детали включены 13 августа 2020 г. 00:45:49 13 августа 2020 г., 00:46:29 КОРОТКАЯ Обычно числовые и кратчайшие из возможных 13.08.20 00:47 13.08.20, 00:47
Форматирование LocalTime
В следующих примерах кода мы покажем, как заставить некоторые из предопределенных средств форматирования выполнять эту работу за нас, а также создавать собственные. Требуется всего несколько строк кода:
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
LocalTime time = LocalTime.now();
System.out.println(time.format(formatter));
Результат:
5:17:00 AM
Тем не менее, мы должны быть осторожны при использовании стандартных
средств форматирования. В этом случае мы не можем использовать
FormatStyle.LONG
или FormatStyle.FULL
, потому что они также дают
некоторую информацию о часовом поясе, которая обычно не сохраняется в
объекте LocalTime
Посмотрим, как это будет выглядеть, когда мы создадим собственный узор:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss a");
LocalTime time = LocalTime.now();
System.out.println(time.format(formatter));
Это выводит:
10:58:28 AM
Конечно, вы можете повозиться с шаблоном.
Форматирование LocalDate
Все классы, поддерживаемые DateTimeFormatter
имеют
format(DateTimeFormatter f)
, поэтому процесс применения шаблона
довольно прост:
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
LocalDate d = LocalDate.now();
System.out.println(d.format(formatter));
Этот фрагмент кода дает:
Thursday, August 13, 2020
Форматирование LocalDateTime
Форматирование LocalDateTime
выполняется таким же образом:
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.MEDIUM);
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime.format(formatter));
Результат:
August 13, 2020, 5:29:28 AM
По такому же принципу создаются нестандартные узоры:
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("eee, MMM dd. yyyy.\nHH:mm:ss a");
LocalDateTime dt = LocalDateTime.now();
System.out.println(dt.format(formatter));
Этот фрагмент кода дает:
Tue, Aug 25. 2020.
11:05:20 AM
Форматирование ZonedDateTime
На этот раз мы можем случайно использовать предопределенный форматер для полного вывода:
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL);
ZonedDateTime dateTime = ZonedDateTime.now();
System.out.println(dateTime.format(formatter));
Этот фрагмент кода выводит:
Thursday, August 13, 2020 at 5:32:49 AM Central European Summer Time
Когда дело доходит до создания собственных шаблонов для ZonedDateTime
, у нас есть полная свобода использовать любой спецификатор, который нам
нужен:
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("eee, MMM dd. yyyy.\nHH:mm:ss a - zzzz");
ZonedDateTime dateTime = ZonedDateTime.now();
System.out.println(dateTime.format(formatter));
Это выводит:
Tue, Aug 25. 2020.
11:09:27 AM - Central European Summer Time
Правила форматирования
Спецификаторы формата для DateTimeFormatter
немного отличаются от
SimpleDateFormat
. Если вы привыкли работать с SimpleDateFormat
,
вам придется немного изменить некоторые привычки:
Персонаж Компонент даты Тип содержимого Пример или времени
Г / г Год Год 1969; 69
M Месяц в году Число / текст Август; Август; 08
ш Неделя в году Число 21 год
W Неделя в месяц Число 2
d День в месяце Число 07; 15
D День в году Число 176
Q / Q Квартал года Число / текст 2: Q2: 2-й квартал
F День недели в Число 2; 3
месяце\
(например, второй
вторник в этом
месяце)
E Название дня Текст Понедельник; пн; недели пн
э / с Локализованный Число / текст Понедельник; Пн; день в неделю Пн; 1; 01
ты Номер дня недели\ Число 1 (Понедельник = 1)
а Маркер am / pm Текст ДО ПОЛУДНЯ, ПОСЛЕ ПОЛУДНЯ
час Час в am / pm Число 12 (1-12)
ЧАС Час в день (0-23) Число 0
k Час в день (1-24) Число 24
K Час в am / pm Число 0 (0-11)
м Минута в час Число 43 год
s Секунда в минуту Число 58
S Доля секунды Доля 965
А Мили дня Число 1234
п Нано секунды Число 566787434
N Нано дня Число 56678743400
z Название часового Название зоны Тихоокеанское пояса стандартное время; Тихоокеанское стандартное время
V ID часового пояса ID зоны Америка / Лос-Анджелес; Z; -08: 30
v Название часового Название зоны Тихоокеанский пояса часовой пояс; PT0
грамм Обозначение эпохи Текст AD; Anno Domini; A
- Текст - если используется менее 4 символов шаблона, компонент отображается в краткой форме. Ровно 4 символа шаблона будут использовать полную форму, а ровно 5 - узкую форму.
- Число - количество символов шаблона - это минимальное количество
цифр. Если это число больше, чем количество цифр, которые нам
действительно нужны для представления числа, тогда к числу
добавляется префикс с соответствующим количеством нулей.
c
иF
могут иметь только одно вхождение, тогда какd
,H
,h
,K
,k
,m
иs
могут иметь два вхождения. ТолькоD
можно использовать до трех раз. - Число / текст - если используются 3 или более символа шаблона, компонент представлен в текстовой форме; иначе по количеству.
- Дробь - возможное количество символов от 1 до 9. Если указано менее 9 из них, значение усекается, и выводятся только самые старшие цифры.
- Год - если количество символов шаблона равно 2, год усекается до двух крайних правых цифр, в противном случае он интерпретируется как число.
- Идентификатор зоны - если используются 2 символа шаблона, выводится идентификатор зоны; в противном случае создается исключение.
- Имя зоны - если символ шаблона -
z
выходными данными будет имя зоны с учетом перехода на летнее время. Если информации для определения того, применяется ли летнее время, недостаточно, будет использовано имя без учета перехода на летнее время. Если количество символов равно 1, 2 или 3, то выводится короткое имя; если 4 выводится полное имя. Пять или более символов вызывают исключение. Что касается символаv
, DST игнорируется. Если используется 1 символ шаблона, то выводится короткое имя; если используются 4, на выходе будет полное имя. Любое другое количество символов вызывает исключение.
Заключение
В этой статье мы продемонстрировали, как форматировать LocalDate
,
LocalTime
, LocalDateTime
и ZonedDateTime
с помощью класса
DateTimeFormatter