tl;dr
This fails.
OffsetDateTime.now()
.format(
DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG )
) // throws DateTimeException.
But the same moment with same offset in a ZonedDateTime works.
Why?
Details
When letting java.time automatically localize the string representation of a OffsetDateTime via DateTimeFormatter.ofLocalizedDateTime, calling format works if the formatter carries a FormatStyle of SHORT or MEDIUM. But when the formatter carries LONG or FULL, a DateTimeException is thrown. Yet ZonedDateTime succeeds using the same moment with the same offset. Why?
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG ) ;
OffsetDateTime odt = OffsetDateTime.now( ZoneId.systemDefault() ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( odt.getOffset() ) ; // Generate a `ZonedDateTime` with same moment and same offset as the `OffsetDateTime`.
// Succeeds.
String outputZdt = zdt.format( f ) ;
System.out.println( "outputZdt: " + outputZdt ) ;
// Fails. Throws exception.
if ( false ) {
String outputOdt = odt.format( f ) ; // Throws exception.
System.out.println( "outputOdt: " + outputOdt ) ;
}
See this code run live at IdeOne.com.
When run…
The good.
outputZdt: September 16, 2017 8:42:14 AM Z
The bad.
Exception in thread "main" java.time.DateTimeException: Unable to extract value: class java.time.OffsetDateTime
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:282)
at java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.format(DateTimeFormatterBuilder.java:3682)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
at java.time.format.DateTimeFormatterBuilder$LocalizedPrinterParser.format(DateTimeFormatterBuilder.java:4347)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
at java.time.OffsetDateTime.format(OffsetDateTime.java:1674)
at Ideone.main(Main.java:28)
I wrote the core of that code to work around the exception thrown, odt.atZoneSameInstant( odt.getOffset() ). Then I realized, why doesn’t java.time do the same thing internally? Why should the OffsetDateTime fail to format where a ZonedDateTime with the same moment and the same offset succeeds? Why should I need to do this conversion from OffsetDateTime to ZonedDateTime?
➟ Is this behavior of OffsetDateTime formatting failure a bug or a feature?
I would file a bug report, but I want to make sure I am misunderstanding something.