我不清楚。由于某些原因,当我尝试使用LocalDateTime格式化DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withLocale(...)实例时,出现异常:


  java.time.DateTimeException:无法提取值:class
  java.time.LocalDateTime


仅当我使用FormatStyle.LONG时,它才会发生,例如,对于FormatStyle.MEDIUM可以正常工作。

这是我的测试:

@Test
public void dateTest() {
    LocalDateTime now = LocalDateTime.now();

    // this is ok. prints a value
    System.out.println("LocalDateTime now (formatted with locale): "
            + now.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
                                                       .withLocale(new Locale("it"))));

    // this fails with java.time.DateTimeException: Unable to extract value: class java.time.LocalDateTime
    // only if FormatStyle.LONG (as it is now)
    System.out.println("LocalDateTime now (formatted with locale): "
            + now.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
                                                       .withLocale(new Locale("it"))));
}


有什么好的解释吗?

最佳答案

tl; dr


  有什么好的解释吗?


是。

LONGFULL格式需要时区或从UTC偏移。您的LocalDateTime缺少任何区域或偏移量。

您使用的LocalDateTime.now不正确。您只能使用Instant(或OffsetDateTime / ZonedDateTime)捕获当前时刻。

Instant.now()  // Capture the current moment as seen in UTC.


为了更灵活地生成字符串,请使用OffsetDateTimeZonedDateTime

ZonedDateTime.now(
    ZoneId.of( "Pacific/Auckland" )
)
.format(
    DateTimeFormatter.ofLocalizedDateTime(
        FormatStyle.LONG   // Or `FULL`.
    )
    .withLocale( Locale.ITALY )
)



  NZDT 2019年3月6日10:22:23


并且,使用FormatStyle.FULL


  mercoledì6 marzo 2019 10:23:25 Ora legale della Nuova Zelanda


LocalDateTime不是片刻

LocalDateTime类仅是日期和时间。它故意缺少任何时区或从UTC偏移的概念。因此,根据定义,它不能代表片刻。

永远不要拨打LocalDateTime.now()


  LocalDateTime.now();


永远不要这样做,永远不要在now上调用LocalDateTime。我无法想到任何实际情况都需要这样做。

跟踪时刻时切勿使用LocalDateTimeLocalDateTime只是日期和时间,仅此而已。没有time zoneoffset-from-UTC的上下文,LocalDateTime不能代表时刻。它代表了大约26-27小时(当前全球时区范围)内的潜在时刻。

LocalDateTime就像说“今年1月23日中午”。您是在日本东京或印度加尔各答(印度)中午吗?也许是法国巴黎?蒙特利尔魁北克省?这些地方的中午发生在不同的时刻,每个时刻之间经过了几个小时。

LocalDateTime中的“本地”是指任何位置或每个位置,但并不表示任何特定位置。

捕捉当前时刻

要跟踪时刻,请使用以下类别之一:


Instant在UTC的时刻,总是在UTC
OffsetDateTime与UTC偏移的时刻,即在UTC基线(格林威治的Royal Observatory处子午线)的基线之前或之后的小时-分钟-秒数。
通过特定地区(时区)的人们所使用的挂钟时间所看到的时刻。


通常,最佳做法是在UTC工作,而忘记自己的时区。

Instant instant = Instant.now() ;


如果要使用某个区域的挂钟时间:

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( instant ) ;


ZonedDateTimeinstant都表示同一时刻,时间轴上的同一点。只有挂钟时间不同。

或者,您可以跳过zdt

ZonedDateTime zdt = ZonedDateTime.now( z ) ;


格式InstantLONG需要一个时区

这两种格式样式:


FULL
FormatStyle.LONG


…两者都需要时区作为显示的一部分。

如上所述,FormatStyle.FULL对象没有区域或偏移量。因此,将LocalDateTimeLONG格式与这样的对象一起使用是没有意义的。

提示:FUL在大多数常见的面向业务的应用程序中通常不是您想要的类。仅在明确考虑到特定问题时才使用该类,例如,将来预约的时间足够长,以至于您冒着政治家重新定义时区偏移的风险(在大多数政体中,他们经常这样做)。跟踪特定时刻时,请先考虑使用LocalDateTime

关于java - 使用Locale格式化LocalDateTime实例时获取java.time.DateTimeException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54991260/

10-11 22:10