包java.util中日期类与;包java.sql

包java.util中日期类与;包java.sql,java,date,Java,Date,在java中,java.util和java.sql包都包含一个Date类,那么它们之间的区别是什么呢 如果Java中存在一个Date类,那么另一个Date类需要什么 来自: 围绕毫秒值的精简包装器,允许JDBC将其标识为SQL日期值。毫秒值表示自1970年1月1日00:00:00.000 GMT以来经过的毫秒数 为了符合SQL日期的定义,必须通过将实例关联的特定时区中的小时、分钟、秒和毫秒设置为零来“规范化”由java.SQL.DATE实例包装的毫秒值 说明:Ajava.util.Date表示日

在java中,
java.util
java.sql
包都包含一个
Date
类,那么它们之间的区别是什么呢

如果Java中存在一个
Date
类,那么另一个
Date
类需要什么

来自:

围绕毫秒值的精简包装器,允许JDBC将其标识为SQL日期值。毫秒值表示自1970年1月1日00:00:00.000 GMT以来经过的毫秒数

为了符合SQL日期的定义,必须通过将实例关联的特定时区中的小时、分钟、秒和毫秒设置为零来“规范化”由
java.SQL.DATE
实例包装的毫秒值


说明:A
java.util.Date
表示日期和时间,A
java.sql.Date
只表示日期(java.sql.Date的补码是,它只表示一天中的一个时间,还扩展了
java.util.Date
)。


java.sql.Date扩展了java.util.Date。需要注意的主要区别是java.sql.Date没有时间组件。

java.sql.Date接受一个长整数,表示自1970年1月1日以来的毫秒数。如果给定的数字为负数,则表示1970年1月1日之前的时间。请记住,对象中封装的值仅表示1970年1月1日这样的日期,并且不存储时间信息

Date存储日期和时间信息。
它比java.sql.Date更常用。

这些答案似乎有些过时

我刚刚读了一点API代码(Java版本1.8.091),在Java.sql.Date中发现了这一点:

/**
 * Creates a date which corresponds to the day determined by the supplied
 * milliseconds time value {@code theDate}.
 *
 * @param theDate
 *            a time value in milliseconds since the epoch - January 1 1970
 *            00:00:00 GMT. The time value (hours, minutes, seconds,
 *            milliseconds) stored in the {@code Date} object is adjusted to
 *            correspond to 00:00:00 GMT on the day determined by the supplied
 *            time value.
 */
public Date(long theDate) {
    super(normalizeTime(theDate));
}

/*
 * Private method which normalizes a Time value, removing all low
 * significance digits corresponding to milliseconds, seconds, minutes and
 * hours, so that the returned Time value corresponds to 00:00:00 GMT on a
 * particular day.
 */
private static long normalizeTime(long theTime) {
    return theTime;
}
标准化时间的方法仍然存在,甚至评论说,时间将标准化为00:00:00 GMT,但它没有任何作用。出于某种原因,他们删除了规范化,这意味着
java.sql.Date
java.util.Date
一样只包含自1970年1月1日以来的毫秒数。因此,有一个时间组件,但它不显示在外部

例如代码

java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(Calendar.getInstance().getTimeInMillis())

System.out.println(utilDate);
System.out.println(sqlDate);
产生输出

Thu Jun 02 13:17:35 CEST 2016
2016-06-02
因此,要小心处理sql日期,不要像处理日期那样只包含日期而不包含时间信息。例如:

java.sql.Date sqlDate1 = new java.sql.Date(Calendar.getInstance().getTimeInMillis());
java.sql.Date sqlDate2 = new java.sql.Date(Calendar.getInstance().getTimeInMillis());

System.out.println(sqlDate1);
System.out.println(sqlDate2);
System.out.println(sqlDate1.equals(sqlDate2));
System.out.println(sqlDate1.toString().equals(sqlDate2.toString()));
印刷品:

2016-06-02
2016-06-02
false
true
旧的
java.util.Date
这个类是旧的日期时间类的一部分,这些类被证明设计得很糟糕,容易混淆,而且很麻烦。其目的是在时间线上表示一个时刻(日期和一天中的某个时间)

该类似乎表示UTC中的一个时刻,除了它的
toString
方法在生成字符串时静默地应用JVM的当前默认时区,这会造成java.util.Date有时区但实际上没有时区的错觉。实际上,它的源代码中有一个时区,用于内部的一些事情,但不明显,不可设置,也不可获取。混乱不堪

java.sql.Date
通过表示a仅日期值(其含义是)使情况变得更糟,但通过扩展
java.util.date
将其作为一种攻击。但是,您应该假装它不是一个子类,正如类doc中所指示的那样。此外,它有一天中的某个时刻,但通过调整到一天中的第一个时刻来假装没有。混乱不堪

还有一件事,
java.sql.Date
类增加了一个小数秒,分辨率为。这超出了java.util.Date使用的解析。许多数据库支持更精细的分辨率,如10或纳秒

因此,在这些旧的日期时间类中,无法真正表示没有时间或时区的仅日期值

新的 该框架起到了解救作用。受到高度成功项目的启发。内置于Java 8及更高版本中,更进一步。看

Instant
该类以UTC表示时间线上的一个时刻,分辨率为纳秒。简洁明了

Instant instant = Instant.now();
instant.toString()→ 2016-06-19T02:34:55.564Z

如果需要
java.util.Date
与旧代码一起使用,则可以转换。请参见添加到旧类的新方法:和

分区 要调整到某个位置,请应用()来获取对象。更好的是,如果你知道正确的时区名称,可以申请一个来获得一个

例如,在下面的代码中,我们看到的是前一天晚上10点(22:00),而不是上面的示例中的凌晨2点。追溯到前天午夜的四个小时。但是上面看到的
instant
对象和接下来看到的
zdt
对象都代表了时间线上相同的同时时刻。历史上同样的时刻,但在巴黎、加尔各答和奥克兰是“明天”,而在蒙特勒尔、墨西哥城和火奴鲁鲁是“昨天”

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
zdt.toString()→ 2016-06-18T22:34:55.564-04:00[美国/蒙特利尔]

LocalDate
对于仅日期值,请使用类。不保留一天中的任何时间或时区

LocalDate localDate = zdt.toLocalDate();
但请注意,时区对于确定日期至关重要,因为对于任何给定的时刻,全球各地的日期都可能因时区而异。因此,上面关于指定时区的讨论已经结束。例如,下一步看我们如何得到6月18日而不是19日

localDate.toString()→ 2016-06-18

如果按时区划分的日期之间的这种差异对您的业务非常重要,那么您应该使用存储在数据库列中的日期时间值,该列类型为带时区的
TIMESTAMP
,而不是
date

搜索堆栈溢出以获取更多信息
java.sql.Date mySqlDate = java.sql.Date.valueOf( localDate );
LocalDate localDate = mySqlDate.toLocalDate();