浪费时间
一个问题可能是java.sql.Date应该是...
“规范化”通过在特定的小时,分钟,秒和毫秒设置为零与实例关联的时区。
......根据the documentation。这意味着,日期时间的时间部分将从java.util.Date或Joda-Time DateTime对象中清除。
没有时区
随着correct answer by Gilbert Le Blanc笔记,既java.util.Date和java.sql.Date没有内部时区的概念。它们存储自Unix epoch以来的毫秒数。
这些类拉一个讨厌的把戏:他们的toString
方法将您的JVM的默认时区应用到字符串的呈现。很混乱。 Date
对象没有时区,但在显示为字符串时会看到时区。
如果您的java.util.Date对象包含自纪元(1970年开始)以来的1344902399000L毫秒的数量,那意味着UTC/GMT中的2012-08-13T23:59:59.000Z
。但是如果你的JVM相信自己在法国的夏令时(DST)有效,你会看到UTC/GMT提前2小时:2012-08-14T01:59:59.000+02:00
在该类中描述的可怕的字符串格式。同一时刻在不同的时区有不同的日月含义(13对14),时钟在墙上已经过了午夜。
乔达时间救援
的Joda-Time 2.4库可以帮助这里。将java.sql.Date或java.util.Date对象连同UTC time zone object一起传递给DateTime构造函数,以清楚地了解您挣扎的价值。
java.util.Date date = new java.util.Date(1390276603054L);
DateTime dateTimeUtc = new DateTime(date, DateTimeZone.UTC);
System.out.println("dateTimeUtc: " + dateTimeUtc);
运行时...
2014-01-21T03:56:43.054Z
要在另一方向乔达,时间java.util.Date转换...
java.util.Date date = myDateTime.toDate();
要在另一方向乔达,时间转换java.sql.Date ...
java.sql.Date date = new java.sql.Date(myDateTime.getMillis());
更新 - 时间
Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。
java.util.Date
的等价物是Instant
。 Instant
类表示UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数点后最多九(9)位数字)。
Instant instant = Instant.ofEpochMilli(1390276603054L);
应用时区,ZoneId
,产生ZonedDateTime
这是类似于一个java.util.Calendar
和乔达时间DateTime
。
ZoneId z = ZoneId.of("Europe/Kaliningrad");
ZonedDateTime zdt = instant.atZone(z);
现在提取一个日期只值,即ZonedDateTime
的日期部分,如一个LocalDate
。 LocalDate
类表示没有时间和不带时区的仅限日期的值。所以LocalDate
就是java.sql.Date
假装是:仅限日期的价值。
LocalDate localDate = zdt.toLocalDate() ;
在JDBC 4.2和更高版本,您可以直接与兼容驱动程序通过PreparedStatement::setObject
和ResultSet::getObject
使用java.time类型。
myPreparedStatement.setObject(… , localDate);
...和...
LocalDate ld = myResultSet.getObject(… , LocalDate.class);
对于较旧的不兼容的驱动程序,简单地转换为java.sql.Date
对象/从LocalDate
通过使用添加到老班的新方法:toLocalDate
和valueOf(LocalDate)
。
什么是回来的路?是否:_new java.sql.Date(jodaDateTimeValue.withZone(DateTimeZone.UTC).getMillis())_? – 2014-02-20 09:41:58
@ thomas.mc.work不,从Joda-Time DateTime对象到java.util.Date比这更容易......只需调用'toDate'方法即可。像这样:'java.util.Date date = myDateTime.toDate();'。对于java。** sql **。Date,您已经接近但不需要UTC,因为Millis始终是UTC。所以:'java.sql.Date date = new java.sql.Date(myDateTime.getMillis());' – 2014-02-20 09:46:54
但是当我用这种方式从值“2014-02-01”的数据库转换java.sql.Date然后我得到“2014-01-31T23:00:00.000Z”(我的时区是CET)。当我使用时区CET时,它是正确的:“2014-02-01T00:00:00.000Z”。这是为什么? – 2014-02-20 13:23:52