【问题标题】:convert String "yyyy-MM-dd" to LocalDateTime将字符串“yyyy-MM-dd”转换为 LocalDateTime
【发布时间】:2017-08-03 10:30:33
【问题描述】:

有没有办法将日期String 转换为LocalDateTime 格式为"yyyy-MM-dd"

如果我试试这个:

DateTimeFormatter DATEFORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime ldt = LocalDateTime.parse(string, DATEFORMATTER);

我遇到了这个异常:

java.time.format.DateTimeParseException: Text '2017-03-13' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2017-03-13 of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
    at java.time.LocalDateTime.parse(LocalDateTime.java:492)
    at hu.npsh.workforce.utils.Util.stringToLocalDateTime(Util.java:284)
    at hu.npsh.workforce.utils.util.StringLocalDateTimeConversionTest.stringToLocalDateTimeTest(StringLocalDateTimeConversionTest.java:35)
    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:498)
    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.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2017-03-13 of type java.time.format.Parsed
    at java.time.LocalDateTime.from(LocalDateTime.java:461)
    at java.time.format.Parsed.query(Parsed.java:226)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    ... 26 more
Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {},ISO resolved to 2017-03-13 of type java.time.format.Parsed
    at java.time.LocalTime.from(LocalTime.java:409)
    at java.time.LocalDateTime.from(LocalDateTime.java:457)
    ... 28 more

我知道主要问题是模式不包含小时和分钟.. 但是,如果我想创建一个方法,得到 StringDateTimeFormatter 并且我想返回 LocalDateTime

有正确的、好的解决方案吗?

编辑:

我的目标是创建一个方法,得到 StringDateTimeFormatter 并返回LocalDateTime。 模式可以是任何东西(什么是有效的)。

【问题讨论】:

  • 使用 LocalDate 或将虚拟 hh:ss 字符串 (00:00) 附加到您的初始字符串
  • @Fildor 感谢通知,我编辑了它。
  • 2017-03-13 解析为LocalDateTime 的预期结果是什么?如果字符串和模式包含分钟,但既不包含小时也不包含秒怎么办?还是反过来?看来你有严格的要求。
  • 这能回答你的问题吗? Parse YYYY-MM-DD dates using the local timezone
  • @Oswaldo JavaScript 问题如何与 Java 问题重复?

标签: java date java-8 date-parsing


【解决方案1】:

您不能将“2017-03-13”转换为LocalDateTime,因为字符串中没有时间信息,只有日期。您可以将其转换为LocalDate

DateTimeFormatter dateformatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate ld = LocalDate.parse("2017-03-13", dateformatter);

之后我们可以将其转换为LocalDateTime

LocalDateTime ldt = ld.atStartOfDay();

【讨论】:

  • 我明白这一点,但我的目标是创建一个方法,得到 StringDateTimeFormatter 并返回 LocalDateTime。模式可以是任何东西(什么是有效的)。
【解决方案2】:

使用LocalDate创建一个localDate,然后您可以根据需要添加时间段:

    DateTimeFormatter DATEFORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate ld = LocalDate.parse("2017-03-13", DATEFORMATTER);
    LocalDateTime ldt = LocalDateTime.of(ld, LocalDateTime.now().toLocalTime());
    System.out.println(ldt);

LocalDateTime

ldt = LocalDateTime.of(ld, LocalDateTime.MIN.toLocalTime());

如果你只需要一个空的时间段

编辑:

看看这个解决方案,你可以构建你的动态解析器​​:

    DateTimeFormatter DATEFORMATTER1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    DateTimeFormatter DATEFORMATTER = new DateTimeFormatterBuilder().append(DATEFORMATTER1)
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
    .toFormatter();

    //DateTimeFormatter DATEFORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDateTime ldt = LocalDateTime.parse("2017-03-13", DATEFORMATTER);

【讨论】:

  • 我正在考虑这是一个很好的解决方案,但是如果 dateformatter 模式更改为包含 Hour 和 Minutes 的模式呢?所以我想创建一个方法,它的参数是字符串和日期格式化程序。如果模式不包含小时和分钟,它应该处理,并使 LocalDateTime 与 init (00:00) 小时和分钟
  • 使用字符串不是一个好主意。在这种情况下,您应该使用重载方法
  • 是的,我知道.. 但就我而言,这是必要的,而且会很有用。但我尝试用其他方式解决
【解决方案3】:

使用 Joda-Time-XX.jar 它有 DateTimeFormatter 将日期转换为日期时间格式。您可以提供日期时间(yyyy-MM-dd HH:mm:ss 格式)或单独提供日期。在这两种情况下,您都会得到日期和时间。

DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime dateTime =  dateTimeFormatter.parseDateTime(date);

【讨论】:

  • 在标准环境中拥有外部库时为什么要外部库?
  • 你能给上面的代码示例,没有任何外部jar吗?
  • 它适用于 java 8 及更高版本,但 java 6 或 7 呢?
  • 问题是关于 Java-8 的,您可以在标签中看到
  • @Sandeep Joda-Time 项目处于维护模式,其团队建议迁移到 java.time 类。在 ThreeTen-Backport 项目中,大部分 java.time 功能都向后移植到 Java 6 和 7。在 ThreeTenABP 项目中进一步适用于 Android。
【解决方案4】:

一天的开始,您可以使用:

LocalDate.parse("2017-10-18", DateTimeFormatter.ofPattern("yyyy-MM-dd"))
.atStartOfDay().atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ISO_DATE_TIME)

一天结束时,您可以使用:

LocalDate.parse("2017-10-18", DateTimeFormatter.ofPattern("yyyy-MM-dd"))                        
.atStartOfDay().plusHours(23).plusMinutes(59).plusSeconds(59).atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ISO_DATE_TIME)

对于 localDateTime,您可以使用:

LocalDate.parse("2017-10-18", DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.now())
.atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"))

结果:

2017-10-18T00:00:00Z
2017-10-18T23:59:59Z
2017-10-18T14:45:35Z

【讨论】:

    【解决方案5】:

    一个班轮怎么样?

    LocalDateTime.parse("2017-03-13" + " 00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm"));
    

    【讨论】:

      【解决方案6】:

      如果您有一个格式为“yyyyMMdd”的字符串中的日期,并且想要转换为 localDate,请按照以下步骤操作:

      public static void processDate() {
          DateTimeFormatter DATEFORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
          LocalDate ld = LocalDate.parse("20200511", DATEFORMATTER);
          System.out.println(ld.toString());
      }
      

      输出为“yyyy-MM-dd”格式:

      2020-05-11
      

      【讨论】:

        猜你喜欢
        • 2020-05-10
        • 1970-01-01
        • 1970-01-01
        • 2013-06-30
        • 2018-05-19
        • 2019-01-26
        • 1970-01-01
        • 2014-04-24
        • 2017-05-30
        相关资源
        最近更新 更多