【问题标题】:Convert Joda LocalDate or java.util.Date to LocalDateTime having time at Start of the Day将 Joda LocalDate 或 java.util.Date 转换为 LocalDateTime 在一天的开始有时间
【发布时间】:2015-02-05 10:28:35
【问题描述】:

我正在使用 Joda 2.5

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

作为,我可以将 LocalDate 转换为 DateTime,时间为 atStartOfDay。我想要相同的功能,但通过 LocalDateTime 对象。

我的代码是:

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

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

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

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 中。

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

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

但不是 LocalDate 到 DateTime

【问题讨论】:

标签: java datetime jodatime


【解决方案1】:

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 项目现在位于maintenance mode,团队建议迁移到java.time 类。见Tutorial by Oracle

解析你的输入字符串

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

未分区

如果您的业务问题缺少任何与 UTC 或时区的偏移,不是时间线上的特定时刻,那么通过转换为LocalDateTime

LocalDateTime ldt = ld.atStartOfDay() ;

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

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

myPreparedStatement.setObject( … , ldt ) ;

……和……

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

分区

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

一天的第一刻并不总是 00:00:00。诸如Daylight Saving Time (DST) 之类的异常意味着一天可能从另一个时间开始,例如 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 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

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

从哪里获得 java.time 类?

  • Java SE 8Java SE 9 及更高版本
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实现。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6Java SE 7
    • ThreeTen-Backport 中的大部分 java.time 功能都向后移植到 Java 6 和 7。
  • Android
    • java.time 类的 Android 捆绑包实现的更高版本。
    • 对于早期的 Android (ThreeTenABP 项目采用 ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案2】:

    好吧,一旦你摆脱了时区异常,你可能只是假设每天从午夜开始,所以使用:

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

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

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

    【讨论】:

      猜你喜欢
      • 2011-08-01
      • 2017-04-14
      • 2012-02-18
      • 2015-12-30
      • 2019-07-22
      • 1970-01-01
      • 2015-07-08
      • 2021-11-26
      相关资源
      最近更新 更多