如何把java.sql.Timestamp转换成java.util.Date?

Mar*_*rów 44 java timestamp date

这段代码

startDate = new Date(timestampValue.getTime));
Run Code Online (Sandbox Code Playgroud)

给我 :

2012-16-02 05:16:17

什么时候

System.out.println(timestampValue);
Run Code Online (Sandbox Code Playgroud)

回报:

2012-01-02 05:16:17.0

小智 50

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

您可以直接指定TimeStampDate引用的对象:

TimeStamp timeStamp = //whatever value you have;
Date startDate = timestampValue;
Run Code Online (Sandbox Code Playgroud)

  • @jelies:**不,它不应该**.根据[Java docs](http://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html):`由于Timestamp类和java.util.Date之间的差异class ...建议代码不要将Timestamp值一般视为java.util.Date的一个实例.Timestamp和java.util.Date之间的继承关系实际上表示实现继承,而不是类型继承 (32认同)
  • 哇,你是对的......这种继承是非常误导性的:/正确答案是[这里](http://stackoverflow.com/a/11839276/787375). (6认同)

Jam*_*mie 18

您应该使用日历:

Calendar start = Calendar.getInstance();
start.setTimeInMillis( timeStampValue.getTime() );
Run Code Online (Sandbox Code Playgroud)


Bas*_*que 11

TL;博士

Instant instant = myResultSet.getObject( … , Instant.class ) ;
Run Code Online (Sandbox Code Playgroud)

...或者,如果您的JDBC驱动程序不支持可选项Instant,则需要支持OffsetDateTime:

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

既避免java.util.Date&java.sql.Timestamp.它们已被java.time类所取代.具体而言,Instant该类表示UTC时间轴上的时刻,分辨率为纳秒(小数部分的最多九(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);
Run Code Online (Sandbox Code Playgroud)

现在提取count-of-milliseconds-since- epoch来实例化java.util.Date对象.

// Date
long millis2 = ts.getTime();
java.util.Date date = new java.util.Date( millis2 );
Run Code Online (Sandbox Code Playgroud)

将值转储到控制台.

System.out.println("millis1 = " + millis1 );
System.out.println("ts = " + ts );
System.out.println("millis2 = " + millis2 );
System.out.println("date = " + date );
Run Code Online (Sandbox Code Playgroud)

跑步时

millis1 = 1434666385642
ts = 2015-06-18 15:26:25.642
millis2 = 1434666385642
date = Thu Jun 18 15:26:25 PDT 2015
Run Code Online (Sandbox Code Playgroud)

因此,问题中显示的代码确实是从java.sql.Timestamp转换为java.util.Date的有效方法,尽管您将丢失任何纳秒数据.

java.util.Date someDate = new Date( someJUTimestamp.getTime() ); 
Run Code Online (Sandbox Code Playgroud)

字符串输出的不同格式

请注意,toString方法的输出是不同的格式,如文档所述.java.sql.Timestamp遵循SQL格式,类似于ISO 8601格式但没有T中间格式.

忽略继承

正如对其他Answers和Question的评论所讨论的那样,你应该忽略java.sql.Timestamp继承自java.util.Date这一事实.该jsTimestamp商务部明确指出,你应该查看一个作为一个子类的其他的:(重点煤矿)

由于Timestamp类和上面提到的java.util.Date类之间存在差异,因此建议代码不要将Timestamp值一般视为java.util.Date的实例.Timestamp和java.util.Date之间的继承关系实际上表示实现继承,而不是类型继承.

如果您忽略Java团队的建议并采取这样的观点,一个关键问题是您将丢失数据:由于Date只有毫秒级的分辨率,因此可能来自数据库的任何微秒纳秒部分都会丢失.

基本上,所有从Java的早期旧日期,时间类是一团糟:java.util.Date,j.u.Calendar,java.text.SimpleDateFormat,java.sql.Timestamp/ .Date/ .Time.他们是行业中日期时间框架的第一个勇敢的努力之一,但最终他们失败了.具体来说,java.sql.Timestamp是一个java.util.Date,其上加了纳秒; 这是一个黑客,不是很好的设计.

java.time

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

而是尽可能使用Java 8及更高版本中内置的java.time包(Tutorial).

java.time的基础知识... Instant在UTC的时间轴上是一个时刻.应用时区(ZoneId)来获得ZonedDateTime.

使用Java.time从Java 8开始的示例代码.使用支持JDBC 4.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.
Run Code Online (Sandbox Code Playgroud)

您可能希望调整为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 ) ;
Run Code Online (Sandbox Code Playgroud)

执行您的业务逻辑.在这里,我们只需添加一天.

ZonedDateTime zdtNextDay = zdt.plusDays( 1 ); // Add a day to get "day after".
Run Code Online (Sandbox Code Playgroud)

在最后阶段,如果绝对需要,请转换为java.util.Date以实现互操作性.

java.util.Date dateNextDay = Date.from( zdtNextDay.toInstant( ) );  // WARNING: Losing data (the nanoseconds resolution).
Run Code Online (Sandbox Code Playgroud)

转储到控制台.

System.out.println( "instant = " + instant );
System.out.println( "zdt = " + zdt );
System.out.println( "zdtNextDay = " + zdtNextDay );
System.out.println( "dateNextDay = " + dateNextDay );
Run Code Online (Sandbox Code Playgroud)

跑步时

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
Run Code Online (Sandbox Code Playgroud)

转换

如果必须使用旧版类型与尚未针对java.time更新的旧代码进行交互,则可以进行转换.使用添加到旧java.util.Date和java.sql.*类的新方法进行转换.

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

…和…

java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;
Run Code Online (Sandbox Code Playgroud)

有关转换的详细信息,请参阅教程章节,旧版日期时间代码.

分数秒

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


关于java.time

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

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

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

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

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.


Pie*_*ine 6

问题可能来自于Date已被弃用的事实.

考虑使用

java.util.Calendar中

要么

乔达时间

编辑2015:

Java 8及更高版本内置了新的java.time包,类似于Joda-Time.