我不清楚。由于某些原因,当我尝试使用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"))));
}
对此有什么好的解释吗?
答案 0 :(得分:2)
对于FormatStyle.LONG
,您必须使用:
ZonedDateTime.now()
代替:
LocalDateTime.now()
因为ZonedDateTime
为您提供了很多细节,而不是LocalDateTime
。
使用FormatStyle.LONG
时,格式化程序会搜索ZoneId
中找不到的其他信息,例如LocalDateTime
,因此会出现异常情况
答案 1 :(得分:2)
对此有什么好的解释吗?
是的
LONG
和FULL
格式需要时区或UTC偏移量。您的LocalDateTime
缺少任何区域或偏移量。
您对 LocalDateTime.now
的使用不正确。您只应使用Instant
(或OffsetDateTime
/ ZonedDateTime
)捕获当前时刻。
Instant.now() // Capture the current moment as seen in UTC.
要更灵活地生成字符串,请使用OffsetDateTime
或ZonedDateTime
。
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ì2019年3月6日10:23:25 Ora legale della Nuova Zelanda
LocalDateTime
暂时不是 LocalDateTime
类仅是日期和时间。它故意缺少任何时区或从UTC偏移的概念。因此,根据定义,它不能代表片刻。
LocalDateTime.now()
LocalDateTime.now();
永远不要执行此操作,永远不要在LocalDateTime
上调用now
。我无法想到任何实际情况都需要这样做。
跟踪时刻时切勿使用LocalDateTime
。 LocalDateTime
仅仅是日期和时间,仅此而已。没有time zone或offset-from-UTC的上下文,LocalDateTime
不能代表时刻。它表示大约26-27小时范围内的潜在时刻,这是全球各地时区的当前范围。
LocalDateTime
就像是说“今年1月23日中午”。您是在日本东京或印度加尔各答(印度)中午吗?或者也许是法国巴黎?蒙特利尔魁北克省?这些地方的中午发生在不同的时刻,每个时刻之间经过了几个小时。
LocalDateTime
中的“本地”表示任何本地,或每个本地,但是不是表示任何特殊的位置。
要跟踪时刻,请使用以下类别之一:
Instant
OffsetDateTime
通常,最佳做法是在UTC工作,而忘记自己的时区。
Instant instant = Instant.now() ;
如果要使用某个地区的挂钟时间:
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( instant ) ;
instant
和zdt
都表示相同的同时时刻,即时间轴上的相同单点。只有挂钟时间不同。
或者您可以跳过Instant
。
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
LONG
和FULL
需要时区这两种格式样式:
... 都需要时区作为其显示的一部分。
如上所述,LocalDateTime
对象没有区域或偏移量。因此,将LONG
或FUL
格式与这样的对象一起使用是没有意义的。
提示:LocalDateTime
在大多数常见的面向业务的应用程序中并不是您想要的类。仅当您明确考虑到特定问题时才使用该类,例如,将来预约的时间足够长,以至于您冒着政治家重新定义时区偏移的风险(在大多数政体中,他们经常这样做)。跟踪特定时刻时,请先考虑使用Instant
。
答案 2 :(得分:0)
当前(Java“ 1.8.0_162”)FormatStyle.FULL和.LONG仅适用于.format(日期) LocalDateTime没有存储很多问题的细节。
详细信息: https://coderanch.com/t/690125/java/java-time-DateTimeException-FormatStyle-LONG