将DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL)与LocalTime实例一起使用时的DateTimeException

iam*_*der 6 java datetime-format java-8 java-date

在Java 8 Date Time API中,我将使用DateTimeFormatter以下API 打印时间:

DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL);
LocalTime time = LocalTime.of(12, 45, 0);
System.out.println(timeFormatter.format(time));
Run Code Online (Sandbox Code Playgroud)

FormatStyle.FULL- 这种格式样式适用于LocalDateLocalDateTime实例.但是在LocalTime实例中抛出异常:

java.time.DateTimeException: Unable to extract value: class java.time.format.DateTimePrintContext$1
Run Code Online (Sandbox Code Playgroud)

根据文件:

public enum FormatStyle {
    // ordered from large to small

    /**
     * Full text style, with the most detail.
     * For example, the format might be 'Tuesday, April 12, 1952 AD' or '3:30:42pm PST'.
     */
    FULL,
Run Code Online (Sandbox Code Playgroud)

为什么会抛出异常?

Mar*_*vin 13

看起来你受到JDK-JDK-8085887的攻击:java.time.format.FormatStyle.LONG或FULL导致未经检查的异常(在JDK 9中修复).

该例外的原因在第一条评论中说明:

打印时间几乎总是需要知道时区并且可用.LocalDateTime没有时区的字段或值.

评论还指出,由于模式不同,这是区域性的,但这可能与您的案例无关.不过我会把它包括在内作为参考:

程序在不同的区域设置中显示不同的行为,因为所选的区域设置特定模式可能包含或不包含模式字母,而不是打印时区或区域偏移.这些模式包括字母:V,z,O,X或x需要时区.

在查看diff(例如in DateTimeFormatter)时,您可以看到它们只是更新了javadoc以反映它(对异常消息进行了一些额外的改进):

@@ -617,10 +617,13 @@
      * looking up the pattern required on demand.
      * <p>
      * The returned formatter has a chronology of ISO set to ensure dates in
      * other calendar systems are correctly converted.
      * It has no override zone and uses the {@link ResolverStyle#SMART SMART} resolver style.
+     * The {@code FULL} and {@code LONG} styles typically require a time-zone.
+     * When formatting using these styles, a {@code ZoneId} must be available,
+     * either by using {@code ZonedDateTime} or {@link DateTimeFormatter#withZone}.
      *
      * @param timeStyle  the formatter style to obtain, not null
      * @return the time formatter, not null
      */
     public static DateTimeFormatter ofLocalizedTime(FormatStyle timeStyle) {
Run Code Online (Sandbox Code Playgroud)

如果您为DateTimeFormatter实例添加时区,则无异常:

DateTimeFormatter timeFormatter = DateTimeFormatter      
                                      .ofLocalizedTime(FormatStyle.FULL)
                                      .withZone(ZoneId.systemDefault());
LocalTime time = LocalTime.of(12, 45, 0);
System.out.println(timeFormatter.format(time));
Run Code Online (Sandbox Code Playgroud)

  • 这仅适用于 JDK 9。 (2认同)