Question
What is the correct way to format an Instant to a String in Java 8 without encountering UnsupportedTemporalTypeException?
Instant instant = ...;
String out = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.format(instant);
Answer
In Java 8, the Instant class represents a specific moment on the timeline, typically in UTC. However, when formatting an Instant to a string using DateTimeFormatter, it is crucial to convert the Instant to a proper temporal type that supports various fields like year, month, and day. The UnsupportedTemporalTypeException occurs because Instant does not directly support all the fields of a date-time pattern.
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
Instant instant = ...;
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
String out = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(zdt);
Causes
- Using DateTimeFormatter with a pattern (like 'yyyy-MM-dd HH:mm:ss') that requires date fields (year, month) directly on an Instant.
- Failed conversion due to the Instant's lack of local date/time fields.
Solutions
- Convert the Instant to a ZonedDateTime or LocalDateTime before formatting.
- Use ZoneId to specify the time zone when converting the Instant.
Common Mistakes
Mistake: Directly formatting an Instant without conversion.
Solution: Always convert the Instant to ZonedDateTime or LocalDateTime when formatting.
Mistake: Not specifying the ZoneId, leading to unwanted time zone behavior.
Solution: Always specify ZoneId to ensure correct local time interpretation.
Helpers
- Java 8 format Instant
- UnsupportedTemporalTypeException
- DateTimeFormatter
- Java 8 Date and Time API
- formatting Instant to String