将Joda LocalDate或java.util.Date转换为在当天开始时有时间的LocalDateTime

我正在使用Joda 2.5

在将Joda LocalDate转换为LocalDateTime时遇到问题。

因为,我可以使用Time atStartOfDay将LocalDate转换为DateTime。 我想通过LocalDateTime对象获得相同的function。

我的代码是:

假设日期来自不同的REST服务,比方说

Date currentDate = new Date("2015-02-05"); 

现在这个Date被传递给另一个服务,如下所示:

 funService(currentDate); public funService(Date currentDate) { LocalDate localDateObject = new LocalDate(date); // Now I have to convert this Date to LocalDateTime LocalDateTime localDateTime = localDateObject.toDateTimeAtStartOfDay(); //But this returns DateTime Object. // As I don't want to store the DateTime Object because it also stores the TimeZone } 

我想要LocalDateTime对象,因为我将此LocalDateTime存储为mysql中的Timestamp。

请提供将LocalDate转换为LocalDateTime对象的解决方案。

例如:’2015-02-01’到’2015-02-01 00:00:01’YYYY-MM-DD到YYYY-MM-DD HH:MM:SS:zzz

但不是LocalDate到DateTime

一旦你摆脱了时区exception,你可以假设每天都在午夜开始,所以使用:

 LocalDateTime localDateTime = localDate.toLocalDateTime(LocalTime.MIDNIGHT); 

目前尚不清楚为什么你想在午夜过后1秒结束。 如果你真的想要它,创建自己的常量LocalTime表示,并在上面的代码中使用它而不是MIDNIGHT

另请注意,如果您确实有一个Date ,则可能已经丢失了信息。 听起来传入的数据实际上是一个字符串 – 您最好直接将其解析为LocalDate以避免时区可能导致问题。

TL;博士

 myPreparedStatement.setObject( // Insert object into database for `TIMESTAMP WITHOUT TIME ZONE` type of column. … , LocalDate.parse( "2015-02-05" ) // Parse input string to a date-only value lacking time-of-day and lacking time zone. .atStartOfDay() // Determine start of a generic 24-hour day for a `LocalDateTime` object lacking offset-from-UTC and lacking time zone. ) ; 

java.time

Joda-Time项目现在处于维护模式 ,团队建议迁移到java.time类。 请参阅Oracle教程 。

解析输入字符串

 LocalDate ld = LocalDate.parse( "2015-02-05" ) ; 

不分区

如果您的业务问题缺少任何来自UTC或时区的偏移, 不是时间线上的特定时刻,那么通过转换为LocalDateTime获取通用24小时日的第一个时刻。

 LocalDateTime ldt = ld.atStartOfDay() ; 

ldt.toString():2015-02-05T00:00

要将其存储在数据库中的数据类型列中,类似于SQL标准类型TIMESTAMP WITHOUT TIME ZONE ,请将java.time对象与符合JDBC 4.2及更高版本的JDBC驱动程序一起使用。 最好与数据库交换对象而不仅仅是字符串。

 myPreparedStatement.setObject( … , ldt ) ; 

…和…

 LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ; 

如果您的业务问题确实需要偏移或区域,则必须指定在时间线上获取实际点。

一天的第一时刻并不总是00:00:00。 夏令时(DST)等exception意味着该日可能会在另一个时间开始,例如01:00:00。 让java.time通过调用LocalDate::atStartOfDay来确定一天中的第一个时刻。

 ZoneId z = ZoneId.of( "Africa/Tunis" ) ; ZonedDateTime zdt = ld.atStartOfDay( z ) ; 

zdt.toString():2015-02-05T00:00 + 01:00 [非洲/突尼斯]

如上所示,使用您的数据库交换java.time对象。 如果您尝试记录历史记录中的实际时刻,则数据库列的类型应等于SQL标准TIMESTAMP WITH TIME ZONE

 myPreparedStatement.setObject( … , zdt ) ; 

…和…

 LocalDateTime ldt = myResultSet.getObject( … , ZonedDateTime.class ) ; 

您的驱动程序和/或数据库可能会将此类分区值转换为UTC值。 或者您可以自己明确地这样做。 提取始终为UTC的Instant对象。

 myPreparedStatement.setObject( … , zdt.toInstant() ) ; 

…和…

 Instant instant = myResultSet.getObject( … , Instant.class ) ; ZonedDateTime zdt = instant.atZone( z ) ; 

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。

您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC驱动程序 。 不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

  • Java SE 8Java SE 9及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6Java SE 7
    • 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
  • Android的
    • 更高版本的Android捆绑java.time类的实现。
    • 对于早期的Android(<26), ThreeTenABP项目采用ThreeTen-Backport (如上所述)。 请参见如何使用ThreeTenABP ….

ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如IntervalYearWeekYearQuarter等。