这对我来说尚不清楚。由于某种原因,当我尝试使用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
有没有很好的解释?
是。
LONG
和FULL
格式需要时区或Offset-from-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ì6Marzo 2019 10:23:25 Ora Legale Della Nuova Zelanda
LocalDateTime
是不是时刻
LocalDateTime
类只是日期和时间。它故意缺乏任何时区或从UTC上取消的任何概念。因此,根据定义,它不能表示片刻。
切勿致电LocalDateTime.now()
LocalDateTime.now();
永远不要这样做,切勿在LocalDateTime
上拨打now
。我想不出任何实际情况都可以这样做。
在跟踪时刻时切勿使用LocalDateTime
。LocalDateTime
仅仅是日期和时间,仅此而已。如果没有时区域或偏移范围的上下文,则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 ) ;
instant
和zdt
都代表同一时刻,时间线上相同的单点。只有墙壁锁定时间是不同的。
,也可以跳过Instant
。
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
格式LONG
&FULL
需要时区
这两种格式样式:
-
FormatStyle.LONG
-
FormatStyle.FULL
…两个都需要时区作为其显示的一部分。
如上所述,LocalDateTime
对象没有区域或偏移。因此,将其使用LONG
或FUL
格式与这样的对象使用毫无意义。
提示: LocalDateTime
通常是您在最常见的面向业务的应用中所需的类。仅当您清楚地牢记特定问题时,只会使用该课程,例如将来的预订预约足够远,您会冒着重新定义时区偏移的风险(在大多数政治中,他们经常会这样做)。在跟踪特定时刻时,首先考虑使用Instant
。