如何从java.sql.Timestamp转换为java.util.Date?

如何从java.sql.Timestamp转换为java.util.Date?,java,date,timestamp,Java,Date,Timestamp,即此代码 startDate = new Date(timestampValue.getTime)); 给我: 2012-16-02 05:16:17 什么时候 返回: 2012-01-02 05:16:17.0问题可能来自日期不推荐这一事实 考虑使用 java.util.Calendar 或 编辑2015: Java 8及更高版本具有内置的新功能,类似于。您应该使用: 类java.sql.TimeStamp扩展自java.util.Date 您可以直接将时间戳对象分配给日期引用: Time

此代码

startDate = new Date(timestampValue.getTime));
给我:

2012-16-02 05:16:17

什么时候

返回:


2012-01-02 05:16:17.0

问题可能来自日期不推荐这一事实

考虑使用

java.util.Calendar

编辑2015:

Java 8及更高版本具有内置的新功能,类似于。

您应该使用:


java.sql.TimeStamp
扩展自
java.util.Date

您可以直接将
时间戳
对象分配给
日期
引用:

TimeStamp timeStamp = //whatever value you have;
Date startDate = timestampValue;

全新的Java8方式是
Date.from(timestamp.toInstant())
。见我的类似答案。

tl;博士 …或者,如果您的JDBC驱动程序不支持可选的
Instant
,则需要支持
OffsetDateTime

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
避免两者兼而有之&。他们被班级取代了。具体来说,表示时间线上某一时刻的类,其分辨率为(最多九(9)位小数)

不同的价值观→ 未验证问题 解决问题的主要部分:“当java.util.Date和java.sql.Timestamp对象从另一个派生时,为什么两者之间的日期不同?”

你的代码一定有问题。您没有发布代码,因此我们无法查明问题所在

首先,您为java.util.Date的值显示的字符串值不是来自其默认的
toString
方法,因此您显然在执行其他操作

其次,当我运行类似的代码时,我确实得到了完全相同的日期时间值

首先创建一个java.sql.Timestamp对象

// Timestamp
long millis1 =  new java.util.Date().getTime();
java.sql.Timestamp ts = new java.sql.Timestamp(millis1);
现在提取毫秒数,以实例化java.util.Date对象

// Date
long millis2 = ts.getTime();
java.util.Date date = new java.util.Date( millis2 );
将值转储到控制台

System.out.println("millis1 = " + millis1 );
System.out.println("ts = " + ts );
System.out.println("millis2 = " + millis2 );
System.out.println("date = " + date );
System.out.println( "instant = " + instant );
System.out.println( "zdt = " + zdt );
System.out.println( "zdtNextDay = " + zdtNextDay );
System.out.println( "dateNextDay = " + dateNextDay );
跑步的时候

instant = 2015-06-18T16:44:13.123456789Z
zdt = 2015-06-18T19:44:13.123456789-04:00[America/Montreal]
zdtNextDay = 2015-06-19T19:44:13.123456789-04:00[America/Montreal]
dateNextDay = Fri Jun 19 16:44:13 PDT 2015
millis1=143466385642
ts=2015-06-1815:26:25.642
毫秒2=143466385642
日期=2015年6月18日星期四15:26:25 PDT
因此,问题中显示的代码确实是从java.sql.Timestamp转换为java.util.Date的有效方法,尽管会丢失任何数据

不同格式的字符串输出 请注意,
toString
方法的输出是一种不同的格式,如文档所示。java.sql.Timestamp遵循sql格式,与格式类似,但中间没有
T

忽略继承 正如在其他答案和问题的评论中所讨论的,您应该忽略java.sql.Timestamp继承自java.util.Date这一事实。明确指出,您不应将其中一个视为另一个的子类型:(强调我的)

由于Timestamp类和上面提到的java.util.Date类之间的差异,建议代码不要将时间戳值一般地作为java.util.Date的实例来查看。Timestamp和java.util.Date之间的继承关系实际上表示实现继承,而不是类型继承

如果您忽略Java团队的建议并采取这样的观点,一个关键问题是您将丢失数据:可能来自数据库的任何或部分秒都将丢失,因为日期只有解析

基本上,早期Java的所有旧日期时间类都是一团乱麻:
Java.util.date
j.u.Calendar
Java.text.simpleDataFormat
Java.sql.Timestamp
/
.date
/
.time
。他们是业内最早在日期时间框架下做出的勇敢努力之一,但最终以失败告终。特别是在这里,java.sql.Timestamp是一个附加了纳秒的java.util.Date;这是一个黑客,不是好的设计

java.time 避免与早期版本的Java捆绑在一起的旧日期时间类

尽可能使用Java 8和更高版本中内置的()

java.time的基础知识,
即时
是UTC时间轴上的一个时刻。应用时区(
ZoneId
)以获取
zoneDateTime

从Java8开始使用java.time的示例代码。使用支持JDBC4.2及更高版本的JDBC驱动程序,您可以直接与数据库交换java.time类;不需要遗留类

Instant instant = myResultSet.getObject( … , Instant.class) ;  // Instant is the raw underlying data, an instantaneous point on the time-line stored as a count of nanoseconds since epoch.
您可能需要调整到UTC以外的时区

ZoneId z = ZoneId.of( "America/Montreal" );  // Always make time zone explicit rather than relying implicitly on the JVM’s current default time zone being applied.
ZonedDateTime zdt = instant.atZone( z ) ;
执行您的业务逻辑。在这里,我们只需添加一天

ZonedDateTime zdtNextDay = zdt.plusDays( 1 ); // Add a day to get "day after".
在最后一个阶段,如果绝对需要,请转换为java.util.Date以实现互操作性

java.util.Date dateNextDay = Date.from( zdtNextDay.toInstant( ) );  // WARNING: Losing data (the nanoseconds resolution).
转储到控制台

System.out.println("millis1 = " + millis1 );
System.out.println("ts = " + ts );
System.out.println("millis2 = " + millis2 );
System.out.println("date = " + date );
System.out.println( "instant = " + instant );
System.out.println( "zdt = " + zdt );
System.out.println( "zdtNextDay = " + zdtNextDay );
System.out.println( "dateNextDay = " + dateNextDay );
跑步的时候

instant = 2015-06-18T16:44:13.123456789Z
zdt = 2015-06-18T19:44:13.123456789-04:00[America/Montreal]
zdtNextDay = 2015-06-19T19:44:13.123456789-04:00[America/Montreal]
dateNextDay = Fri Jun 19 16:44:13 PDT 2015
转换 如果必须使用遗留类型与尚未更新为java.time的旧代码进行接口,则可以转换。使用添加到旧java.util.Date和java.sql.*类中的新方法进行转换

Instant instant = myJavaSqlTimestamp.toInstant() ;
……还有

java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;
有关转换的更多信息,请参见教程章节

分数秒 注意分数秒的分辨率。从纳秒到毫秒的转换意味着可能会丢失一些数据

    • java.util.Date
    • (启发java.time的框架)
    • java.sql.Timestamp
    • java.time

关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

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

从哪里获得java.time类

  • 然后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
      Instant instant = myJavaSqlTimestamp.toInstant() ;
      
      java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;
      
      java.lang.Object
          java.util.Date
              java.sql.Timestamp
      
      public static Date convertTimestampToDate(Timestamp timestamp)  {
              Instant ins=timestamp.toLocalDateTime().atZone(ZoneId.systemDefault()).toInstant();
              return  Date.from(ins);
      }