即此代码
startDate = new Date(timestampValue.getTime));
给了我:
2012-16-02 05:16:17
当
System.out.println(timestampValue);
返回:
2012-01-02 05:16:17.0
答案 0 :(得分:49)
班级java.sql.TimeStamp
从java.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)
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团队的建议并采取了这样的观点,那么一个关键问题是您将丢失数据:任何microsecond或nanosecond部分时间由于日期只有millisecond分辨率,因此可能会从数据库中丢失。
基本上,早期Java中所有旧的日期时间类都是一团糟:java.util.Date
,j.u.Calendar
,java.text.SimpleDateFormat
,java.sql.Timestamp
/ .Date
/ .Time
。他们是行业中日期时间框架的第一个勇敢的努力之一,但最终他们失败了。具体来说,java.sql.Timestamp是一个java.util.Date,其上加了纳秒;这是一个黑客,不是很好的设计。
避免与早期版本的Java捆绑在一起的旧日期时间类。
而是尽可能使用Java 8及更高版本中内置的java.time package(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.
您可能希望调整为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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 3 :(得分:6)
问题可能来自于不推荐使用Date这一事实。
考虑使用
java.util.Calendar中
或
编辑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>