LocalDate 到 java.util.Date 反之最简单的转换?

LocalDate to java.util.Date and vice versa simplest conversion?

有没有一种简单的方法可以将 LocalDate(在 Java 8 中引入)转换为 java.util.Date 对象?

'simple',我的意思比这个更简单:

Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

这对我来说有点尴尬。

既然我们只对日期部分感兴趣,而且两个对象中都没有时区信息,为什么要明确引入时区?转换时应隐式采用午夜时间和系统默认时区。

免责声明:虽然下面的答案有效,但不建议在生产代码中使用。在这种情况下,应遵循 Basil 的回答中的方法。

其实是有的。 java.sql.Date 对象中有一个静态方法 valueOf 就是这样做的。所以我们有

java.util.Date date = java.sql.Date.valueOf(localDate);

就是这样。没有明确设置时区,因为本地时区是隐含的。

来自文档:

The provided LocalDate is interpreted as the local date in the local time zone.

java.sql.Date子classes java.util.Date所以结果是java.util.Date也。

而在java.sql.Date class中有一个toLocalDate方法用于反向操作。所以我们有:

LocalDate ld = new java.sql.Date(date.getTime()).toLocalDate();

您可以将 java.util.Date 对象转换为 String 对象,这会将日期格式设置为 yyyy-mm-dd。

LocalDate 有一个 parse 方法可以将其转换为 LocalDate 对象。该字符串必须表示有效日期并使用 DateTimeFormatter.ISO_LOCAL_DATE.

进行解析

Date to LocalDate

LocalDate.parse(Date.toString())

tl;博士

Is there a simple way to convert a LocalDate (introduced with Java 8) to java.util.Date object? By 'simple', I mean simpler than this

没有。你做得很好,而且尽可能简洁。

java.util.Date.from(                     // Convert from modern java.time class to troublesome old legacy class.  DO NOT DO THIS unless you must, to inter operate with old code not yet updated for java.time.
    myLocalDate                          // `LocalDate` class represents a date-only, without time-of-day and without time zone nor offset-from-UTC. 
    .atStartOfDay(                       // Let java.time determine the first moment of the day on that date in that zone. Never assume the day starts at 00:00:00.
        ZoneId.of( "America/Montreal" )  // Specify time zone using proper name in `continent/region` format, never 3-4 letter pseudo-zones such as “PST”, “CST”, “IST”. 
    )                                    // Produce a `ZonedDateTime` object. 
    .toInstant()                         // Extract an `Instant` object, a moment always in UTC.
)

阅读下面的问题,然后再考虑。怎么可能更简单?如果你问我约会什么时候开始,除了问你“在哪里?”我还能怎么回答?新的一天在法国巴黎比在蒙特利尔更早,在加尔各答更早,在新西兰奥克兰甚至更早,所有不同的时刻。

因此,在将仅日期 (LocalDate) 转换为日期时间时,我们 必须 应用时区 (ZoneId) 以获得分区值 (ZonedDateTime),然后移动到 UTC (Instant) 以匹配 java.util.Date.

的定义

详情

首先,尽可能避免使用旧的遗留日期时间 classes,例如 java.util.Date。它们设计不佳、令人困惑且麻烦。它们被 java.time classes 取代是有原因的,实际上是 许多 原因。

但如果必须,您可以将 to/from java.time 类型转换为旧类型。寻找添加到旧 classes 的新转换方法。

java.util.Datejava.time.LocalDate

请记住,java.util.Date 是用词不当,因为它表示日期 时间,UTC。相反,LocalDate class 表示没有时间和时区的仅日期值。

java.util.Date 到 java.time 意味着转换为 java.time.Instant 的等效 class。 Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds(最多九 (9) 位小数)。

Instant instant = myUtilDate.toInstant();

LocalDate class 表示没有时间和时区的仅日期值。

时区对于确定日期至关重要。对于任何给定时刻,日期在全球范围内因地区而异。例如,Paris France is a new day while still “yesterday” in Montréal Québec.

午夜后几分钟

所以我们需要将 Instant 移动到一个时区。我们应用 ZoneId 得到 ZonedDateTime.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

从那里,要求一个日期,LocalDate

LocalDate ld = zdt.toLocalDate();

java.time.LocalDatejava.util.Date

要移动另一个方向,从 java.time.LocalDatejava.util.Date 意味着我们要从仅日期到日期时间。所以我们必须指定一天中的时间。你可能想在一天的第一时间去。不要不要假设那是00:00:00。夏令时 (DST) 等异常意味着第一个时刻可能是另一个时间,例如 01:00:00。让 java.time 通过在 LocalDate.

上调用 atStartOfDay 来确定该值
ZonedDateTime zdt = myLocalDate.atStartOfDay( z );

现在提取一个Instant.

Instant instant = zdt.toInstant();

通过调用 from( Instant )Instant 转换为 java.util.Date

java.util.Date d = java.util.Date.from( instant );

更多信息


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* classes。 Hibernate 5 和 JPA 2.2 支持 java.time.

在哪里获取 java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

我用下面的解决方案解决了这个问题

  import org.joda.time.LocalDate;
  Date myDate = new Date();
  LocalDate localDate = LocalDate.fromDateFields(myDate);
  System.out.println("My date using Date" Nov 18 11:23:33 BRST 2016);
  System.out.println("My date using joda.time LocalTime" 2016-11-18);

在这种情况下,localDate 以这种格式打印您的日期 "yyyy-MM-dd"

日期 -> LocalDate:

LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

本地日期 -> 日期:

Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

正在将 LocalDateTime 转换为 java.util.Date

    LocalDateTime localDateTime = LocalDateTime.now();

    ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.systemDefault());

    Instant instant = zonedDateTime.toInstant();

    Date date = Date.from(instant);

System.out.println("Result Date is : "+date);

Date to LocalDate

Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

本地日期至今

LocalDate localDate = LocalDate.now();
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());