在java.util.Date或java.sql.Date之间进行选择

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在java.util.Date或java.sql.Date之间进行选择相关的知识,希望对你有一定的参考价值。

我应该使用java.util.Date还是java.sql.Date?

我有一个VisualFox数据库,我使用适当的jdbc类型4驱动程序使用IntelliJ Idea向导检索实体。

ide(或驱动程序)已将日期字段创建为Timestamp。但是,日期字段不是时间戳,而是日期字段,它们仅存储年,月和日。

所以我想知道是否应该切换到java.util.Date或java.sql.Date。乍一看,我认为java.sql.Date应该是适当的,但它有许多声明为弃用的方法。

答案

tl;dr

我应该使用java.util.Date还是java.sql.Date?

都不是。

JDBC 4.2及更高版本开始,两者都已过时。请改用java.time类。

  • 仅限日期的价值 对于类似于SQL标准DATE的数据库类型,请使用java.time.LocalDateLocalDate ld = myResultSet.getObject( … , LocalDate.class ) ; myPreparedStatement.setObject( ld , … ) ;
  • 日期与UTC值的时间 对于类似于SQL标准TIMESTAMP WITH TIME ZONE的数据库类型,请使用java.time.InstantInstant instant = myResultSet.getObject( … , Instant.class ) ; myPreparedStatement.setObject( instant , … ) ;

Details

问题和其他答案似乎过分考虑了这个问题。一个java.sql.Date只是一个java.util.Date,其时间设置为00:00:00

来自the java.sql.Date doc(斜体文字是我的)...

上课日期

java.lang.Object继承

java.util.Date←从j.u.Date继承

Java.SQL.date

一个围绕毫秒值的瘦包装器,允许JDBC将其标识为SQL DATE值。毫秒值表示自1970年1月1日00:00:00.000 GMT以来经过的毫秒数。 ←时间设置为零,午夜GMT / UTC

为了符合SQL DATE的定义,java.sql.Date实例包含的毫秒值必须通过在与实例关联的特定时区中将小时,分钟,秒和毫秒设置为零来“标准化”。 。

Date-Only versus Date-Time

核心问题是:

  • SQL 在SQL中,DATE数据类型仅存储日期,不包含时间。
  • JAVA 在与早期版本的Java捆绑在一起设计糟糕的日期时间库中,它们未能包含一个表示仅限日期的类。

Java团队没有创建一个仅限日期的类,而是制造了一个糟糕的黑客。他们采用了他们的日期时间类(错误的java.util.Date类,包含日期和时间)并将其扩展为将实例设置为时间到午夜UTC00:00:00。那个hack,即j.u.Date的子类,是java.sql.Date

所有这些黑客攻击,糟糕的设计和错误的操作都让人感到困惑。

Which To Use

那么何时使用哪个?简单,经过混乱之后。

  • 在读取或写入数据库的仅限日期列时,请使用java.sql.Date,因为它笨拙地试图掩盖其时间。
  • 在Java的其他任何地方,你需要一个时间和你的约会,使用java.util.Date
  • 如果手头有java.sql.Date但需要java.util.Date,只需传递java.sql.Date即可。作为子类,java.sql.Date是java.util.Date。

Even Better

在现代Java中,您现在可以选择合适的日期时间库来取代与Java捆绑在一起的旧的和臭名昭着的java.util.Date,Calendar,SimpleTextFormat和java.sql.Date类。主要选择是:

两者都提供LocalDate类来代表日期,没有时间和没有时区。

更新到JDBC 4.2或更高版本的JDBC driver可用于直接与数据库交换java.time对象。然后我们可以完全放弃丑陋的混乱,它是java.util。*和java.sql。*包中的日期时间类。

setObject | getObject

Oracle发布的This article解释说,如果调用DATEgetObject方法,Java 8中的JDBC已经透明地更新,以将SQL setObject值映射到新的java.time.LocalDate类型。

用钝的语言,JDBC 4.2 update spec的底部证实了这篇文章,新的映射添加到getObjectsetObject方法。

myPreparedStatement.setObject( … , myLocalDate ) ;

…和…

LocalDate myLocalDate = myResultSet.getObject( … , LocalDate.class ) ;

Convert

该规范还说java.sql.Date类中添加了新方法,可以来回转换为java.time.LocalDate。

Time Zone

旧的java.util.Datejava.sql.Datejava.sql.Timestamp总是在UTC。前两个(至少)有一个深埋在源代码中的时区,但仅在表面下使用,例如equals方法,并且没有getter / setter。

更令人困惑的是,他们的toString方法应用了JVM当前的默认时区。所以对于天真的程序员来说,他们似乎有一个时区,但他们没有。

埋藏时区和toString行为都是避免这些麻烦的旧遗产类别的两个原因之一。

使用java.time(Java 8及更高版本)编写业务逻辑。在java.time缺少的地方,使用Joda-Time。 java.time和Joda-Time都有方便的方法来与需要的旧类来回传递。

替换:

Instant类代表UTC时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

所有三个java.time.Local…类都缺乏time zoneoffset-from-UTC的任何概念。


About java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.Datehtml" rel="nofollow

以上是关于在java.util.Date或java.sql.Date之间进行选择的主要内容,如果未能解决你的问题,请参考以下文章

java.util.Date与java.sql.Date

util.date和sql.date的衔接处理

java.util.Date 和 java.sql.Date 有啥区别? [复制]

java.sql.date和java.util.date的区别和转换

高效开发:java.util.Date和java.sql.Date两者区别

高效开发:java.util.Date和java.sql.Date两者区别