时区之间的转换给出不正确的结果

Conversion between Time Zone gives incorrect results

 DateTime dt = new LocalDateTime(rs.getTimestamp("LastUpdated").getTime()).toDateTime(DateTimeZone.forID("America/New_York")); 

Timestamp t=new Timestamp(dt.getMillis());     

我从中得到的结果与 "America/New_York" 的实际时间不匹配。它关闭了几个小时。可能是什么问题?

更新-

这是我要转换的时间,它来自数据库:2015-04-28 13:14:31这是转换后的时间(从代码中删除 "dt.plusMillis(offset)" 后的代码输出: 2015-04-28 22:44:31.0 这是实际的纽约时间:凌晨 3:45

用JODA库很容易做到。核心 java 库很痛苦,不建议使用。但是,日期和时间库已使用 Java 8.

重新实现

举个例子,假设您尝试将澳大利亚墨尔本时间转换为马德里时间。

这是 Joda 代码;

    LocalDateTime dateTime = new LocalDateTime(2015, 3, 28, 14, 0, 0); 
    DateTime srcDateTime = dateTime.toDateTime(DateTimeZone.forID("Asia/Colombo"));
    DateTime dstDateTime = srcDateTime.withZone(DateTimeZone.forID("America/New_York"));
    Date madridTime =dstDateTime.toLocalDateTime().toDateTime().toDate();


    System.out.println("Asia/Colombo -> "+srcDateTime.toDateTime());
    System.out.println("America/New_York -> "+madridTime);

这是输出:

Asia/Colombo -> 2015-04-28T14:00:00.050+05:30
America/New_York -> Tue Apr 28 04:30:00 EEST 2015

您也可以从 http://www.timezoneconverter.com/

查看

另请参阅:

Date and Time API for JDK 8

tl;博士

myResultSet
.getObject( … , OffsetDateTime.class )   // Returns a `OffsetDateTime` object represent a moment as seen through some offset-from-UTC, a number of hours-minutes-seconds ahead/behind UTC. 
.atZoneSameInstant(                      // Adjusts from a moment with a mere offset to a moment as seen in a time zone.
    ZoneId.of( "America/New_York" )
)

Joda-Time 处于维护模式

仅供参考,Joda-Time project is now in maintenance mode, advising migration to the java.time classes。

LocalDateTime不是片刻

LocalDateTimeclass(在 Joda-Time 和 java.time 中)代表一个时刻,是不是时间轴上的一个点。这个 class 通常不用于商业应用程序,除了 (a) 将来的预约,以及 (b) 代表一个日期,该日期可以适用于 any 地点但不是特定地点。

避免java.sql.Timestamp

显然您从 ResultSet 中检索到 java.sql.Timestamp 对象。停止这样做。

OffsetDateTime

这个可怕的 class 多年前被 java.time classes 取代,特别是 OffsetDateTime when used with JDBC 4.2 及更高版本。

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

ZonedDateTime

要查看此 moment in the New York region’s time zone, apply a ZoneId to get a ZonedDateTime 对象。

ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

同一时刻,时间轴上相同的同时点,不同的挂钟时间。

弄清楚offset和zone的区别:

  • Offset-from-UTC
    简单的小时-分钟-秒数。领先于 UTC(向东)为正,落后于 UTC(向西)为负。
  • Time zone
    一个时区。时区是过去、现在和未来(计划中的)特定地区人们使用的偏移量变化的历史。


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

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

从哪里获得java.time classes?

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.