使用区域设置格式化 LocalDateTime 实例时获取 java.time.DateTimeException
Getting java.time.DateTimeException when formatting LocalDateTime instance with Locale
我不清楚。出于某种原因,当我尝试使用 DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withLocale(...)
格式化 LocalDateTime
实例时,出现异常:
java.time.DateTimeException: Unable to extract value: 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"))));
}
有什么好的解释吗?
使用 FormatStyle.LONG
你必须使用 :
ZonedDateTime.now()
而不是:
LocalDateTime.now()
因为 ZonedDateTime
给了你很多细节,不像 LocalDateTime
。
当您使用 FormatStyle.LONG
时,格式化程序会搜索 ZoneId
等在 LocalDateTime
中找不到的其他信息,因此您会得到异常
tl;博士
Is there any good explanation for that?
是的。
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ì 6 marzo 2019 10:23:25 Ora legale della Nuova Zelanda
LocalDateTime
不是片刻
LocalDateTime
class 只是一个日期和时间。它故意缺少任何时区或与 UTC 的偏移量的概念。所以,根据定义,它不能代表一个时刻。
从不调用 LocalDateTime.now()
LocalDateTime.now();
永远不要这样做,永远不要在 LocalDateTime
上调用 now
。我想不出任何实际情况会要求这样做。
永远不要在跟踪时刻时使用 LocalDateTime
。 LocalDateTime
只是一个日期和一天中的时间,仅此而已。没有 time zone or offset-from-UTC 的上下文,LocalDateTime
不能代表一个时刻。它代表了大约 26-27 小时范围内的 潜在 时刻,即全球当前的时区范围。
一个LocalDateTime
就像在说“今年1月23日中午”。你是说日本东京还是印度加尔各答的中午?或者法国巴黎?蒙特利尔魁北克?在这些不同的地方,中午发生在不同的时刻,每个时刻都经过了几个小时。
LocalDateTime
中的“本地”是指任何地区,或每个地区,但 not 表示任何 特定的 地点。
捕捉当下
要跟踪某个时刻,请使用以下 classes 之一:
Instant
UTC 时刻,始终为 UTC
OffsetDateTime
A moment with an offset-from-UTC, that is, a number of hours-minutes-seconds ahead of or behind the baseline of UTC (the meridian at Royal Observatory 在格林威治。
ZonedDateTime
通过特定地区(时区)人们使用的挂钟时间看到的时刻。
通常,最佳做法是在 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
在最常见的面向业务的应用程序中通常不是您想要的 class。仅当您清楚地考虑到特定问题时才使用 class,例如在未来预订足够远的约会,以至于您 运行 政客重新定义时区偏移的风险(他们经常做,在大多数政体中)。跟踪特定时刻时,首先考虑使用 Instant
。
我不清楚。出于某种原因,当我尝试使用 DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withLocale(...)
格式化 LocalDateTime
实例时,出现异常:
java.time.DateTimeException: Unable to extract value: 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"))));
}
有什么好的解释吗?
使用 FormatStyle.LONG
你必须使用 :
ZonedDateTime.now()
而不是:
LocalDateTime.now()
因为 ZonedDateTime
给了你很多细节,不像 LocalDateTime
。
当您使用 FormatStyle.LONG
时,格式化程序会搜索 ZoneId
等在 LocalDateTime
中找不到的其他信息,因此您会得到异常
tl;博士
Is there any good explanation for that?
是的。
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ì 6 marzo 2019 10:23:25 Ora legale della Nuova Zelanda
LocalDateTime
不是片刻
LocalDateTime
class 只是一个日期和时间。它故意缺少任何时区或与 UTC 的偏移量的概念。所以,根据定义,它不能代表一个时刻。
从不调用 LocalDateTime.now()
LocalDateTime.now();
永远不要这样做,永远不要在 LocalDateTime
上调用 now
。我想不出任何实际情况会要求这样做。
永远不要在跟踪时刻时使用 LocalDateTime
。 LocalDateTime
只是一个日期和一天中的时间,仅此而已。没有 time zone or offset-from-UTC 的上下文,LocalDateTime
不能代表一个时刻。它代表了大约 26-27 小时范围内的 潜在 时刻,即全球当前的时区范围。
一个LocalDateTime
就像在说“今年1月23日中午”。你是说日本东京还是印度加尔各答的中午?或者法国巴黎?蒙特利尔魁北克?在这些不同的地方,中午发生在不同的时刻,每个时刻都经过了几个小时。
LocalDateTime
中的“本地”是指任何地区,或每个地区,但 not 表示任何 特定的 地点。
捕捉当下
要跟踪某个时刻,请使用以下 classes 之一:
Instant
UTC 时刻,始终为 UTCOffsetDateTime
A moment with an offset-from-UTC, that is, a number of hours-minutes-seconds ahead of or behind the baseline of UTC (the meridian at Royal Observatory 在格林威治。ZonedDateTime
通过特定地区(时区)人们使用的挂钟时间看到的时刻。
通常,最佳做法是在 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
在最常见的面向业务的应用程序中通常不是您想要的 class。仅当您清楚地考虑到特定问题时才使用 class,例如在未来预订足够远的约会,以至于您 运行 政客重新定义时区偏移的风险(他们经常做,在大多数政体中)。跟踪特定时刻时,首先考虑使用 Instant
。