前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JDK 8 中的LocalDate不符合正常逻辑的解析报错: Unable to obtain LocalDateTime from TemporalAccessor: {Year=2019, ...

JDK 8 中的LocalDate不符合正常逻辑的解析报错: Unable to obtain LocalDateTime from TemporalAccessor: {Year=2019, ...

作者头像
一个会写诗的程序员
发布2019-06-25 10:21:02
7.4K0
发布2019-06-25 10:21:02
举报

问题描述

代码语言:javascript
复制
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import java.time.LocalDate
import java.time.format.DateTimeFormatter

@RunWith(JUnit4::class)
class DateTimeTest {

    @Test
    fun test1() {
        val dtf = DateTimeFormatter.ofPattern("yyyyMM")
        val a = LocalDate.parse("201906", dtf) // 报错!!!
        println(a)
    }

    @Test
    fun test2() {
        val formatter = DateTimeFormatter.ofPattern("yyyyMMdd")
        val b = LocalDate.parse("20190601", formatter) // OK
        println(b)
    }

}

报错

代码语言:javascript
复制
java.time.format.DateTimeParseException: Text '201906' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {Year=2019, MonthOfYear=6},ISO of type java.time.format.Parsed

    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)
    at com.alibaba.alibrain.quotareport.util.DateTimeTest.test(DateTimeTest.kt:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {Year=2019, MonthOfYear=6},ISO of type java.time.format.Parsed
    at java.time.LocalDateTime.from(LocalDateTime.java:461)
    at java.time.LocalDateTime$$Lambda$7/1157740463.queryFrom(Unknown Source)
    at java.time.format.Parsed.query(Parsed.java:226)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1849)
    ... 24 more
Caused by: java.time.DateTimeException: Unable to obtain LocalDate from TemporalAccessor: {Year=2019, MonthOfYear=6},ISO of type java.time.format.Parsed
    at java.time.LocalDate.from(LocalDate.java:368)
    at java.time.LocalDateTime.from(LocalDateTime.java:456)
    ... 27 more

采用原生的实现类来实现解析

代码语言:javascript
复制
@Test
fun test2() {
    val s = "201906"
    val dtf = DateTimeFormatterBuilder()
            .appendValue(ChronoField.YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
            .appendValue(ChronoField.MONTH_OF_YEAR, 2)
            .toFormatter()
    val temporalAccessor = dtf.parse(s)
    val year = temporalAccessor.get(ChronoField.YEAR) // 2019
    val month = temporalAccessor.get(ChronoField.MONTH_OF_YEAR) // 6
    val ld = LocalDate.of(year, month, 1)
    val fmt = ld.format(DateTimeFormatter.ofPattern("yyyy-MM"))
    println(fmt) // 2019-06
}

相关问题

I am simply trying to convert a date string into a DateTime object in Java 8. Upon running the following lines:

代码语言:javascript
复制
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime dt = LocalDateTime.parse("20140218", formatter);

I get the following error:

代码语言:javascript
复制
Exception in thread "main" java.time.format.DateTimeParseException: 
Text '20140218' could not be parsed: 
Unable to obtain LocalDateTime from TemporalAccessor: 
{},ISO resolved to 2014-02-18 of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)
The syntax is identical to what has been suggested here, yet I am served with an exception. I am using JDK-8u25.

5个回答

答案1

It turns out Java does not accept a bare Date value as DateTime. Using LocalDate instead of LocalDateTime solves the issue:

代码语言:javascript
复制
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate dt = LocalDate.parse("20140218", formatter);

参考答案2

Expanding on retrography's answer..: I had this same problem even when using LocalDate and not LocalDateTime. The issue was that I had created my DateTimeFormatter using .withResolverStyle(ResolverStyle.STRICT);, so I had to use date pattern uuuuMMdd instead of yyyyMMdd (i.e. "year" instead of "year-of-era")!

代码语言:javascript
复制
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
  .parseStrict()
  .appendPattern("uuuuMMdd")
  .toFormatter()
  .withResolverStyle(ResolverStyle.STRICT);
LocalDate dt = LocalDate.parse("20140218", formatter);

(This solution was originally a comment to retrography's answer, but I was encouraged to post it as a stand-alone answer because it apparently works really well for many people.)

参考答案3 If you really need to transform a date to a LocalDateTime object, you could use the LocalDate.atStartOfDay(). This will give you a LocalDateTime object at the specified date, having the hour, minute and second fields set to 0:

代码语言:javascript
复制
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime time = LocalDateTime.from(LocalDate.parse("20140218", formatter).atStartOfDay());

参考答案4 This is a really unclear and unhelpful error message. After much trial and error I found that LocalDateTime will give the above error if you do not attempt to parse a time. By using LocalDate instead, it works without erroring.

This is poorly documented and the related exception is very unhelpful.

参考答案5 For what is worth if anyone should read again this topic(like me) the correct answer would be in DateTimeFormatter definition, e.g.:

代码语言:javascript
复制
private static DateTimeFormatter DATE_FORMAT =  
            new DateTimeFormatterBuilder().appendPattern("dd/MM/yyyy[ [HH][:mm][:ss][.SSS]]")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
            .toFormatter(); 

One should set the optional fields if they will appear. And the rest of code should be exactly the same.

Unable to obtain LocalDateTime from TemporalAccessor when parsing LocalDateTime (Java 8)

I am simply trying to convert a date string into a DateTime object in Java 8. Upon running the following lines:

代码语言:javascript
复制
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDateTime dt = LocalDateTime.parse("20140218", formatter);

I get the following error:

代码语言:javascript
复制
Exception in thread "main" java.time.format.DateTimeParseException: 
Text '20140218' could not be parsed: 
Unable to obtain LocalDateTime from TemporalAccessor: 
{},ISO resolved to 2014-02-18 of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1918)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1853)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)

The syntax is identical to what has been suggested here, yet I am served with an exception. I am using JDK-8u25.

https://stackoverflow.com/questions/27454025/unable-to-obtain-localdatetime-from-temporalaccessor-when-parsing-localdatetime

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.06.24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述
  • 采用原生的实现类来实现解析
  • 相关问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档