【问题标题】:Time information is missing when converting LocalDate to java.util.Date将 LocalDate 转换为 java.util.Date 时缺少时间信息
【发布时间】:2020-01-04 02:57:10
【问题描述】:

将 LocalDate 转换为 java.util.Date 时缺少时间信息

我的输入日期格式为“2019-08-30T19:47:22+00:00”(字符串)。我必须将其转换为 java.util.Data。我想用 java 8 来做。

String input = "2019-08-30T19:47:22+00:00";
Date date = null;
LocalDate dateTime = LocalDate.parse(input, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
date = Date.from(dateTime.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println("Parsed from LoacalDate: " + date);
System.out.println("From new Date(): " + new Date());

输出

  • 从本地日期解析:8 月 30 日星期五 00:00:00CDT 2019 来自新
  • 日期():2019 年 8 月 30 日星期五 17:16:23 CDT

在输出时间信息丢失。如何获取时间信息?

【问题讨论】:

  • LocalDate 没有时间。如果您需要时间,请查看LocalDateTimeZonedDateTimeOffsetDateTime。但我很好奇你认为dateTime.atStartOfDay() 做了什么。
  • LocalDate 的 javadoc 对那个类有什么看法?它代表什么?
  • 附带问题:为什么必须将其转换为java.util.Datejava.time 已经推出 5 年了 - 您使用的是较旧的 API 吗?很多东西已经成功切换,尤其是 ORM。
  • @Clockwork-Muse 我正在使用图书馆。它期望 java.util.Date 中的日期

标签: java date java-8 localdate


【解决方案1】:

tl;博士

LocalDate 只存储一个日期,所以使用错误的类。

java.util.Date                              // Terrible class, now legacy. Avoid. Replaced by `java.time.Instant` in JSR 310. Use only where required, to interoperate with old code not yet updated for java.time.
.from(                                      // Convert from modern `Instant` to legacy `Date`.
    OffsetDateTime                          // The modern class to represent a moment in the context of an offset-from-UTC (a number of hours-minutes-seconds). Not to be confused with a time zone, which is a history of changes to the offset used by the people of a particular region. 
    .parse( "2019-08-30T19:47:22+00:00" )   // Parse text into an `OffsetDateTime` object.
    .toInstant()                            // Extract an `Instant`, a more basic building-block class that represent a moment in UTC (an offset of zero). 
)
.toString()                                 // Generates text representing the value of the `Date`. But this method lies! It dynamically applies your JVM’s current default time zone while generating the text.

请注意,java.util.Date::toString 会撒谎!该方法动态应用 JVM 的当前默认时区,同时生成表示实际 UTC 值的文本。 从不使用此Date的众多原因之一。

详情

你使用了错误的类。

LocalDate

LocalDate 仅表示日期,没有时间,没有时区或偏移量。

通过将表示时刻的输入解析为简单的日期,您将删除时间和与 UTC 的偏移量。

OffsetDateTime

您的输入 "2019-08-30T19:47:22+00:00" 代表一个时刻:一个日期、一个时间、一个与 UTC 零时分秒的偏移量。所以将其解析为OffsetDateTime

OffsetDateTime odt = OffsetDateTime.parse( "2019-08-30T19:47:22+00:00" ) ;

避免使用旧的日期时间类

java.util.Date很糟糕,不应再使用。几年前,随着 JSR 310 的采用,它被现代的 java.time 类所取代。

但是,如果您必须与尚未更新到 java.time 的旧代码进行互操作,则可以来回转换。查看添加到旧类的新 to…/from… 方法。

java.util.Date 的等价物是java.time.Instant,两者都代表UTC 中的一个时刻(尽管分辨率不同,毫秒与纳秒)。所以从我们更灵活的OffsetDateTime中提取一个基本的Instant对象。

Instant instant = odt.toInstant() ;
java.util.Date d = Date.from( instant ) ;

【讨论】:

    【解决方案2】:

    我能够使用以下代码 sn-p 使其工作

      LocalDateTime dateTime = LocalDateTime.parse(input,DateTimeFormatter.ISO_OFFSET_DATE_TIME);
      date = Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
      System.out.println("Parsed from LoacalDate:" + date);
      System.out.println("From new Date():" + new Date());
    

    【讨论】:

    • Thiagarajan Ramanathan,您正在丢弃字符串 (+00:00) 中的偏移量信息并替换 JVM 默认时区的偏移量,在大多数情况下会导致错误的结果。请注意,您不需要打印为 Fri Aug 30 19:47:22 的 Date,而是表示与字符串相同的时间点的 Date
    猜你喜欢
    • 2019-07-22
    • 2018-07-15
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    相关资源
    最近更新 更多