OffsetDateTime fails with localized formatter using FormatStyle of LONG or FULL

Viewed 2308

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.

2 Answers
Related