Решение ошибки UnsupportedTemporalTypeException в Java

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

LocalDateTime в сочетании с DateTimeFormatter.ofPattern существенно упрощают задачу форматирования дат и времени:

Java
Скопировать код
String formattedDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"));
System.out.println(formattedDate); // например, "2099-12-31 23:59:59"
Кинга Идем в IT: пошаговый план для смены профессии

Основы работы с классами даты и времени и их форматирование

Java API для даты и времени представляет собой большое количество классов для разнообразных задач. Правильный выбор класса поможет избежать ошибок типа UnsupportedTemporalTypeException:

Java
Скопировать код
// Неудача! LocalDate не хранит информацию о времени, отсюда и exception.
String formattedDate = LocalDate.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));

Для работы с датой и временем без учета часового пояса подойдет LocalDateTime:

Java
Скопировать код
String formattedDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"));
System.out.println(formattedDate);

Случаи, когда требуется учет часовых поясов, сложнее. Для этих целей существует ZonedDateTime:

Java
Скопировать код
String formattedDate = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss z"));
System.out.println(formattedDate);

Преобразование и настройка формата дат

Если требуется конвертация времени из эпохи Unix в более удобный для восприятия формат, можно использовать следующий подход:

Java
Скопировать код
long epochMilli = System.currentTimeMillis();
String epochFormattedDate = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss")
        .withZone(ZoneId.systemDefault())
        .format(Instant.ofEpochMilli(epochMilli));
System.out.println(epochFormattedDate);

Для учета различий в локализации дат используйте класс DateTimeFormatter и метод withLocale:

Java
Скопировать код
String esDate = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("EEEE, MMMM d, uuuu", new Locale("es", "ES")));
System.out.println(esDate);

Исключения обрабатываем по-классически:

Java
Скопировать код
try {
    String formattedDate = LocalDate.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
} catch (UnsupportedTemporalTypeException e) {
    e.printStackTrace();
}

Парсинг и сопоставление дат с шаблонами

Разбор строки с датой и временем не должен казаться вами черной магией:

Java
Скопировать код
String inputDate = "2099-12-31T23:59:59";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(inputDate, formatter);

Умение работы с часовыми поясами

Способность корректно работать с ZonedDateTime отличает профессионала от остальных:

Java
Скопировать код
Instant now = Instant.now();
ZonedDateTime zonedDateTime = now.atZone(ZoneId.of("America/New_York"));
System.out.println(zonedDateTime.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss z")));

Визуализация

Умение демонстрировать различные форматы времени, используя соответствующий DateTimeFormatter, является ценным навыком:

Markdown
Скопировать код
| Стиль часов   | Выводимое время     | Метод Java API                          |
| ------------- | ------------------- | -------------------------------------- |
| Цифровой      | '14:45:30'          | DateTimeFormatter.ofPattern("HH:mm:ss")|
| Международный | '2099-12-31'        | DateTimeFormatter.ISO_LOCAL_DATE       |
| Классический  | 'Dec 31, 2099'      | DateTimeFormatter.ofPattern("MMM d, uuuu")  |
| Полный формат | 'Пятница, 31 декабря, 2099' | DateTimeFormatter.ofPattern("EEEE, d MMMM, uuuu") |

Время в Java не ждет, потому важен правильный выбор методов для его обработки.

Углубление в детали даты с использованием ChronoFields

Работа с датой и временем на максимально детальном уровне возможна с использованием ChronoFields:

Java
Скопировать код
LocalDateTime localDateTime = LocalDateTime.now();
String detailedFormat = localDateTime.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSSSSS"));
System.out.println(detailedFormat);

Проверить поддержку конкретного поля в рамках программного кода можно с помощью TemporalAccessor:

Java
Скопировать код
boolean isSupported = localDateTime.isSupported(ChronoField.SECOND_OF_DAY);

Полезные материалы

  1. DateTimeFormatter (Java Platform SE 8) — официальная документация DateTimeFormatter.
  2. datetime – How can I parse/format dates with LocalDateTime? (Java 8) – Stack Overflow — обсуждение использования DateTimeFormatter на форуме Stack Overflow.
  3. Java 8 – New Date/Time API — обучающее руководство по новому API даты и времени в Java 8.
  4. Java Date Time Tutorial — авторитетное руководство по работе с датой и временем в Java 8.
  5. Java LocalDateTime – Javatpoint — примеры использования класса LocalDateTime в Java 8.