转换joda.time.DateTime以java.sql.Date并保留时区(Convert jo

2019-07-30 23:04发布

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.

Answer 1:

浪费时间

一个问题可能是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.DateInstant 。 该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::setObjectResultSet::getObject

myPreparedStatement.setObject( … , localDate );

…和…

LocalDate ld = myResultSet.getObject( … , LocalDate.class );

对于较旧的不兼容的驱动程序,简单地转换为java.sql.Date对象/从LocalDate :通过使用添加到老班新方法toLocalDatevalueOf( LocalDate )



Answer 2:

一个的内部表示java.sql.Date是自1970年以来00年1月1日已通过的毫秒数:00:00.000 GMT。

你确定你不是在看一个toString问题? 该方法toGMTString()虽然贬值,仍然存在。



Answer 3:

我猜你可能需要在配置文件中添加TIMEZONE = GMT

在Web应用程序,这是在web.xml中定义

<context-param> <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</p‌​aram-name> <param-value>true</param-value> </context-param>

问候



文章来源: Convert joda.time.DateTime to java.sql.Date and retain time zone