包java.util中日期类与;包java.sql
在java中,包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.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
表示日期和时间,Ajava.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();