I have the following scenario:
- Swing control that returns a
Calendar
object
- Intermediate
DateTime
object that I use to do heavy date/time manipulation (joda)
- Database connection (
OraclePreparedStatement
) that only takes a java.sql.Date
object
My problem is that the Calendar
and DateTime
objects are properly displaying the date in GMT (which I want), but when I convert to java.sql.Date
in order to send to the database, the date is converted to the local time zone.
For example:
Calendar
and DateTime
are 2012-08-13T23:59:59.000Z (correct GMT)
- Resulting
java.sql.Date
is 2012-08-14 (incorrect local UTC+2 date)
Below is the code I'm using to do the conversion.
DateTime dateGmt = new DateTime(calendarGmt.getTimeInMillis(), DateTimeZone.UTC);
java.sql.Date sqlDate = new java.sql.Date(dateGmt.getMillis());
I don't know how to create a java.sql.Date
object while retaining the correct time zone. It's also entirely possible that I'm doing an incorrect conversion.
浪费时间
一个问题可能是java.sql.Date应该是...
通过在与该实例相关联的特定时区的时,分,秒和毫秒设置为零“规范化”。
...根据文档 。 这意味着,日期时间的时间部分被从java.util.Date或乔达时间datetime对象清除。
没有时区
由于吉尔伯特勒布朗正确答案指出,无论是java.util.Date和java.sql.Date没有内部时区的概念。 它们存储自Unix的毫秒数时代 。
这些类拔下流的手段 :他们toString
方法适用于您的JVM的默认时区字符串的渲染。 很混乱。 该Date
对象没有时区,但是当作为字符串显示你看到一个时区。
如果您的java.util.Date对象包含从新纪元(1970年开始)的1344902399000L毫秒数,这意味着2012-08-13T23:59:59.000Z
在UTC / GMT。 但是如果你的JVM认为自己是在法国与夏令时(DST)的影响,你会看到比UTC / GMT 2小时: 2012-08-14T01:59:59.000+02:00
在类描述可怕的字符串格式。 时间的同一时刻在不同的时区不同天的日意(13 VS 14),与时钟上的墙是过了午夜。
乔达时间救援
该乔达时间 2.4库可以帮助这里。 通过其中的java.sql.Date或java.util.Date对象的DateTime的构造与沿UTC时区对象获得与你苦苦价值的清晰画面。
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() );
更新 - java.time
该乔达时间项目现在处于维护模式,与球队的java.time类建议迁移。
相当于java.util.Date
是Instant
。 该Instant
类表示在时间轴上的时刻UTC ,分辨率为纳秒 (最多9个(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和更高版本,可以通过一个兼容的驱动程序直接使用java.time类型PreparedStatement::setObject
和ResultSet::getObject
。
myPreparedStatement.setObject( … , localDate );
…和…
LocalDate ld = myResultSet.getObject( … , LocalDate.class );
对于较旧的不兼容的驱动程序,简单地转换为java.sql.Date
对象/从LocalDate
:通过使用添加到老班新方法toLocalDate
和valueOf( LocalDate )
。
一个的内部表示java.sql.Date
是自1970年以来00年1月1日已通过的毫秒数:00:00.000 GMT。
你确定你不是在看一个toString
问题? 该方法toGMTString()
虽然贬值,仍然存在。
我猜你可能需要在配置文件中添加TIMEZONE = GMT
在Web应用程序,这是在web.xml中定义
<context-param> <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name> <param-value>true</param-value> </context-param>
问候