Explain Codes LogoExplain Codes Logo

Unsupportedtemporaltypeexception when formatting Instant to String

java
datetimeformatter
instant
date-and-time
Nikita BarsukovbyNikita Barsukov·Nov 21, 2024
TLDR

This is how you convert an Instant to String:

String formatted = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") .format(Instant.now().atOffset(ZoneOffset.UTC));

The Instant requires a ZoneOffset to format, this snippet exactly does that, getting your expected string representation.

When working with Instant and DateTimeFormatter, remember to use the correct time zone and Locale to prevent unexpected results. Here are some important pointers:

  • Choosing the Right Zone: Make sure to set the correct ZoneId or ZoneOffset.
// Because my app runs only in the timezone of Hogwarts DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") .withZone(ZoneId.of("Europe/London"));
  • Locale-Specific Formatting: Cater to different Locale for the correct representation.
// Formatting date for Mr. Mario in his style DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") .withLocale(Locale.ITALY);

Crafting your Time with DateTimeFormatter

DateTimeFormatter offers various pre-defined and custom formatters. Let's dive into ISO-8601 formatting and beyond:

The ISO-8601 Friendly Formatter

For ISO-8601 compliant formatting, you can use DateTimeFormatter.ISO_INSTANT:

// If it is good for the world, It is good for me String isoFormatted = DateTimeFormatter.ISO_INSTANT.format(Instant.now());

Create your Own Style of Queen (or King)

You can define your specific pattern and DateTimeFormatter:

// Because we love verbose styles DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("EEE, MMM dd, yyyy HH:mm:ss"); String customFormatted = customFormatter.format(ZonedDateTime.now());

The Locale Charm

For locale-loving folks, use the ofLocalizedDateTime function:

DateTimeFormatter localFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) .withLocale(Locale.JAPAN); String localFormatted = localFormatter.format(ZonedDateTime.now());

Instant is Time but Time is not Instant

When formatting Instant, achieving high precision and enhancing readability is often a requirement:

Millisecond Precision, Please

For an Instant with millisecond precision:

// Sorry, seconds. Milliseconds are the new cool Instant now = Instant.now().truncatedTo(ChronoUnit.MILLIS);

Reading is Cool

Improve readability by replacing parts of the Instant.toString() output:

// T and Z, you're not my type String readableInstant = Instant.now().toString().replace("T", " ").replace("Z", "");

Is my Formatter Compatible?

Ensure that all patterns in your DateTimeFormatter are compatible with Instant:

// Flush the toilet after use and clean the formatter before use DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss 'UTC'");

User’s Wish, My Command

Dynamic time zones? Here you go!