使用LocaLE格式化LocalDateTime实例时,获取Java.Time.DateTime Exception



这对我来说尚不清楚。由于某种原因,当我尝试使用DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withLocale(...)格式化LocalDateTime实例时,我会得到一个例外:

java.time.datetime exception:无法提取值:类 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"))));
}

是否有很好的解释?

使用FormatStyle.LONG您必须使用:

ZonedDateTime.now()

而不是:

LocalDateTime.now()

因为ZonedDateTime给了您很多细节,而不是LocalDateTime

当您使用FormatStyle.LONG时,formater搜索了LocalDateTime中未找到的其他信息(例如ZoneId),因此您会得到异常

tl; dr

有没有很好的解释?

是。

LONGFULL格式需要时区或Offset-from-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 ) 
)

6 Marzo 2019 10:22:23 NZDT

,使用FormatStyle.FULL

Mercoledì6Marzo 2019 10:23:25 Ora Legale Della Nuova Zelanda

LocalDateTime不是时刻

LocalDateTime类只是日期和时间。它故意缺乏任何时区或从UTC上取消的任何概念。因此,根据定义,它不能表示片刻。

切勿致电LocalDateTime.now()

LocalDateTime.now();

永远不要这样做,切勿在LocalDateTime上拨打now。我想不出任何实际情况都可以这样做。

在跟踪时刻时切勿使用LocalDateTimeLocalDateTime仅仅是日期和时间,仅此而已。如果没有时区域或偏移范围的上下文,则LocalDateTime无法代表一刻。它代表了大约26-27小时的范围电位矩,这是全球各地的当前时区范围。

LocalDateTime就像在说"今年1月23日中午"。您是说东京日本或印度加尔各答的中午吗?还是法国巴黎?魁北克蒙特利尔?在各个地方中午发生在不同的时刻,每个时刻都经过数小时。

LocalDateTime中的"本地"表示任何局部性,或 not not 表示任何特定部。

捕获当前时刻

要跟踪瞬间,请使用以下一类:

  • Instant
    在UTC中的一刻,始终在UTC
  • OffsetDateTime
    与UTC基线(Greenwich的皇家天文台的子午线)前或后面的数分钟或后面的偏移时刻,也就是说。li> ZonedDateTime
    通过特定区域的人们(时区)使用的墙壁锁定时间所见。

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

Instant instant = Instant.now() ;

如果要使用某个区域的墙壁锁定时间:

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

instantzdt都代表同一时刻,时间线上相同的单点。只有墙壁锁定时间是不同的。

,也可以跳过Instant

ZonedDateTime zdt = ZonedDateTime.now( z ) ;

格式LONG&FULL需要时区

这两种格式样式:

  • FormatStyle.LONG
  • FormatStyle.FULL

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

如上所述,LocalDateTime对象没有区域或偏移。因此,将其使用LONGFUL格式与这样的对象使用毫无意义。

提示: LocalDateTime通常是您在最常见的面向业务的应用中所需的类。仅当您清楚地牢记特定问题时,只会使用该课程,例如将来的预订预约足够远,您会冒着重新定义时区偏移的风险(在大多数政治中,他们经常会这样做)。在跟踪特定时刻时,首先考虑使用Instant

最新更新