150

I have the this simple code:

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
LocalDateTime.now().format(FORMATTER)

Then I will get following exception:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds
at java.time.LocalDate.get0(LocalDate.java:680)
at java.time.LocalDate.getLong(LocalDate.java:659)
at java.time.LocalDateTime.getLong(LocalDateTime.java:720)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$OffsetIdPrinterParser.format(DateTimeFormatterBuilder.java:3315)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1745)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1719)
at java.time.LocalDateTime.format(LocalDateTime.java:1746)

How to resolve this issue?

Matthias Braun
  • 28,341
  • 18
  • 134
  • 157
carfield
  • 1,939
  • 2
  • 14
  • 15

2 Answers2

262

LocalDateTime is a date-time without a time-zone. You specified the time zone offset format symbol in the format, however, LocalDateTime doesn't have such information. That's why the error occured.

If you want time-zone information, you should use ZonedDateTime.

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
ZonedDateTime.now().format(FORMATTER);
=> "20140829 14:12:22.122000 +09"
ntalbs
  • 27,110
  • 8
  • 61
  • 81
43

The prefix "Local" in JSR-310 (aka java.time-package in Java-8) does not indicate that there is a timezone information in internal state of that class (here: LocalDateTime). Despite the often misleading name such classes like LocalDateTime or LocalTime have NO timezone information or offset.

You tried to format such a temporal type (which does not contain any offset) with offset information (indicated by pattern symbol Z). So the formatter tries to access an unavailable information and has to throw the exception you observed.

Solution:

Use a type which has such an offset or timezone information. In JSR-310 this is either OffsetDateTime (which contains an offset but not a timezone including DST-rules) or ZonedDateTime. You can watch out all supported fields of such a type by look-up on the method isSupported(TemporalField).. The field OffsetSeconds is supported in OffsetDateTime and ZonedDateTime, but not in LocalDateTime.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss.SSSSSS Z");
String s = ZonedDateTime.now().format(formatter);
Meno Hochschild
  • 40,702
  • 7
  • 93
  • 118
  • With what prefix would you have replaced the prefix "Local" to avoid confusion? – Matthew Mar 06 '16 at 19:06
  • @Matthew There was also a [debate](https://sourceforge.net/p/threeten/mailman/message/29960633/) initiated by Bank Credit Suisse suggesting the name `PlainDateTime` etc. Probably better because the prefix "plain" does indicate that there is nothing more than just date-time. If we were still before Java v1.0 then no prefix would have been better, but names like `Date` etc. are already reserved by old JDK. – Meno Hochschild Mar 06 '16 at 20:05