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

时间:2012-05-16 15:10:45

标签: java date timestamp

此代码

startDate = new Date(timestampValue.getTime));

给了我:

2012-16-02 05:16:17

System.out.println(timestampValue);

返回:

2012-01-02 05:16:17.0

8 个答案:

答案 0 :(得分:49)

班级java.sql.TimeStampjava.util.Date延伸。

您可以直接将TimeStamp对象分配给Date参考:

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

答案 1 :(得分:17)

您应该使用Calendar代替:

Calendar start = Calendar.getInstance();
start.setTimeInMillis( timeStampValue.getTime() );

答案 2 :(得分:11)

TL;博士

Instant instant = myResultSet.getObject( … , Instant.class ) ;

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

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

同时避免使用java.util.Date& java.sql.Timestamp 即可。它们已被java.time类所取代。具体来说,Instant类代表UTC中时间轴上的时刻,分辨率为nanoseconds(小数部分最多九(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);

现在提取count-of-milliseconds-since - epoch来实例化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 );

跑步时。

millis1 = 1434666385642
ts = 2015-06-18 15:26:25.642
millis2 = 1434666385642
date = Thu Jun 18 15:26:25 PDT 2015

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

java.util.Date someDate = new Date( someJUTimestamp.getTime() ); 

字符串输出的不同格式

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

忽略继承

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

  

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

如果您忽略了Java团队的建议并采取了这样的观点,那么一个关键问题是您将丢失数据:任何microsecondnanosecond部分时间由于日期只有millisecond分辨率,因此可能会从数据库中丢失。

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

java.time

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

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

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.

您可能希望调整为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( "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 ) ;

有关转化的详情,请参阅教程章节Legacy Date-Time Code

分数秒

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

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

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

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 3 :(得分:6)

问题可能来自于不推荐使用Date这一事实。

考虑使用

java.util.Calendar中

Joda-Time

编辑2015:

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

答案 4 :(得分:3)

public static Date convertTimestampToDate(Timestamp timestamp)  {
        Instant ins=timestamp.toLocalDateTime().atZone(ZoneId.systemDefault()).toInstant();
        return  Date.from(ins);
}

答案 5 :(得分:2)

花哨的新Java 8方式是Date.from(timestamp.toInstant())。请参阅我的类似答案elsewhere

答案 6 :(得分:1)

java.sql.ResultSet rs;
//fill rs somehow
java.sql.Timestamp timestamp = rs.getTimestamp(1); //get first column
long milliseconds = timestamp.getTime() + (timestamp.getNanos() / 1000000);
java.util.Date date = return new java.util.Date(milliseconds);

答案 7 :(得分:1)

时间戳是日期:https://docs.oracle.com/javase/7/docs/api/java/sql/Timestamp.html

    <script src="//d3js.org/d3.v3.min.js"></script>
    <script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
    <div id="map_canvas">
        <canvas></canvas>
    </div>
<script>
var width = $('#map_canvas').width(),
    height = 700;
var ctx;

function zooms() {
    if(d3.event.sourceEvent.button !== 0) {
        return
    }else {

        ofsetx = d3.event.translate[0];
        ofsety = d3.event.translate[1];
        scale = d3.event.scale;
        ctx.save();
        ctx.clearRect(0, 0, width, height);
        ctx.translate(d3.event.translate[0], d3.event.translate[1]);
        ctx.scale(d3.event.scale, d3.event.scale);
        draw()
        ctx.restore();
    }
}

function draw() {
    ctx.beginPath();
    ctx.arc(100,75,50,0,2*Math.PI);
    ctx.stroke();
}

var zoom = d3.behavior.zoom()
    .scaleExtent([-2, 10])
    .on("zoom", zooms)

$(function() {
    ctx = d3.select("canvas")
    .attr("width", width)
    .attr("height", height)
    .attr("ofsetx", 0)
    .attr("ofsety", 0)
    .call(zoom)
    .on("dblclick.zoom", null)
    .on("contextmenu", function (d, i) {
        d3.event.preventDefault();
    })
    .node().getContext("2d");
    draw();
});
</script>