我应该使用java.util.Date还是切换到java.time.LocalDate

Ita*_*tai 50 java date jdbc

编辑:嗯,显然这是基于意见,所以让我试着更准确地改写它 -

在不需要任何向后兼容性的Java代码中使用LocalDate,LocalTime等有任何明确的警告或缺点,如果是这样 - 它们是什么?

我正在寻找像"当前EE库X和Y无法正确使用LocalDate"或"这个非常有用的模式被LocalTime打破"等等.


(这是原始问题供参考)

在Java 8中,引入了新的时间API,即java.time.LocalDate等,但java.util.Date未标记为已弃用.

我正在编写一个新项目,它不需要向后兼容.我应该只使用LocalDate,LocalDateTime等吗?使用这个新API是否有任何缺点,而不是旧的java.util.Date?

特别是 - 我将主要使用JDBC.从我所看到的JDBC很好地处理java.util.Date.它是否适合LocalDate?

搜索产生了许多网站,告诉他们如何从一种格式转换为另一种格式,但是如果新代码使用旧的API,则没有明确的答案.

谢谢.

ger*_*tan 39

尽管名称,java.util.Date可用于存储日期和时间(它存储自纪元以来的UTC毫秒偏移量)

我肯定会使用新的API,因为它具有更强大的功能:

  • 更容易格式化/解析.API有自己的格式/解析方法
  • API包括加法/减法操作(minusMinutes,plusDays等)

以上都不适用于java.util.Date

Old Date也可以像这样转换为LocalDateTime:

Date oldDate = ...
LocalDateTime newDateTime = 
  LocalDateTime.from(Instant.ofEpochMilli(oldDate.getTime()));
Run Code Online (Sandbox Code Playgroud)

  • 因此,在您的意见中,是时候完全丢弃旧Date了吗? (2认同)

Ole*_*.V. 6

Java 8 及更高版本:不用担心

\n\n

不,如果您\xe2\x80\x99 使用的是 Java 8 或更高版本(其中 \xe2\x80\ x99s 内置)。

\n\n

人们唯一可以简单考虑的一件事就是您已经排除的一件事。

\n\n
\n

我正在编写一个新项目,它不需要向后兼容。

\n
\n\n

即使为了向后兼容,您也可以安全地使用 java.time,因为转换方法内置于 Java 8 的旧类中。

\n\n

Java 6 和 7:权衡

\n\n

如果您\xe2\x80\x99使用Java 6或7,则需要使用java.time的ThreeTen-Backport ,并在ThreeTenABP中进一步适应API级别26以下的Android 。如果您\xe2\x80\x99只做了很少的非常简单的日期和时间工作,并且前向兼容性在某种程度上不是一个问题,那么您可以考虑外部依赖项是否值得。请考虑到,您的外部依赖项只是 Java 8 及更高版本中内置内容的向后移植,因此坚如磐石,因此您只需要它,直到迁移到 Java 8 或更高版本。此时您可以更改导入、重新测试并取消向后移植。

\n\n

您可以想到的负债示例

\n\n
\n

当前 EE 库 X 和 Y 无法与 LocalDate 正常工作

\n
\n\n

有一些这样的例子,还有 JDK 中的库类。我的选择是在我自己的代码中使用 java.time,并且仅在调用尚未接受 java.time 类型的 API 之前进行转换。相反,如果我从 API 获取过时类的实例,请首先将其转换,然后使用 java.time 来处理其余的事情。

\n\n
\n

LocalTime 打破了这个非常有用的模式

\n
\n\n

据我所知没有这样的模式。相反,与大多数旧类相比, java.time 使用不可变对象工厂方法模式。

\n


Bas*_*que 5

我要添加到Ole VV正确答案中

JDBC 4.2

特别是-我将主要使用JDBC。

JDBC 4.2添加了对与数据库交换java.time对象的支持。请参见 PreparedStatement::setObjectResultSet::getObject方法。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
myPreparedStatement.setObject( … , today ) ;
Run Code Online (Sandbox Code Playgroud)

恢复。

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
Run Code Online (Sandbox Code Playgroud)

对于逃避我的原因,JDBC规范并没有要求对两种最常用的类支持:InstantZonedDateTime。您的数据库和JDBC驱动程序可能会也可能不会添加对它们的支持。

如果没有,您可以轻松转换。从开始OffsetDateTime,在JDBC中需要支持。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Run Code Online (Sandbox Code Playgroud)

要查看特定地区(时区)人们使用的挂钟时间中的这一时刻,请应用ZoneId来获取ZonedDateTime对象。

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant() ;
Run Code Online (Sandbox Code Playgroud)

要调整为UTC,请提取一个Instant。根据Instant定义,An 始终使用UTC。

Instant instant = odt.toInstant() ;
Run Code Online (Sandbox Code Playgroud)

您可以转换为其他方式,以写入数据库。

myPreparedStatement.setObject( … , zdt.toOffsetDateTime() ;  // Converting from `ZonedDateTime` to `OffsetDateTime`. Same moment, same point on the timeline, different wall-clock time.
Run Code Online (Sandbox Code Playgroud)

…和:

myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ;  // Converting from `Instant` to `OffsetDateTime`. Same moment, same point on the timeline, and even the same offset. `OffsetDateTime` is a more flexible class with abilities such as (a) applying various offsets and (b) flexible formatting when generating text, while `Instant` is meant to be a more basic building-block class. 
Run Code Online (Sandbox Code Playgroud)

注意所使用的命名约定java.timeatfromtowith,等。

Java(现代和旧式)和标准SQL中的日期时间类型表。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar,和SimpleDateFormat

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

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

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

在哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多