Joda-Time DateTime.toDate()恢复时区

我正在尝试使用Joda-Time从一个时区转换为另一个时区。

final DateTimeZone fromTimeZone = DateTimeZone.forID("America/Los_Angeles"); final DateTimeZone toTimeZone = DateTimeZone.forID(toTimeZoneString); DateTime convertedStart = new DateTime(start, fromTimeZone).withZone(toTimeZone); Date finalS = convertedStart.toDate(); 

我看到finalS丢失了时区,当我执行.toDate()时,它会恢复到原始时区。 convertedStart已正确转换。

开始时的forms – > Wed Jun 04 18:15:38 GMT 2014


例:

 start: Wed Jun 04 18:15:38 GMT 2014 toTimeZoneString is Asia/Kolkata convertedStart : 2014-06-05T06:45:38.409+05:30 finalS: Wed Jun 04 18:15:38 GMT 2014 

为什么会这样?

由于您拒绝发布完整的代码示例,我将使用一个小的演示作为答案。

使用Joda-Time 2.3的示例代码。

仅在强制时使用java.util.Date,例如输出/输入到其他类。

 java.util.Date dateIn = new java.util.Date(); // Avoid java.util.Date when possible. 

将日期转换为Joda-Time DateTime,并指定时区。 我随意选择UTC 。 除非业务规则规定使用本地时区,否则大部分或全部业务逻辑应以UTC格式完成。

 DateTime dateTimeUtc = new DateTime( dateIn, DateTimeZone.UTC ); // Convert Date to DateTime, assign UTC time zone. 

调整从UTC到美国西海岸的时区。 使用适当的时区名称 (主要是continent / cityOrRegion)而不是3或4个字母代码,这些代码既不是标准化也不是唯一的。

 DateTimeZone timeZoneLos_Angeles = DateTimeZone.forID( "America/Los_Angeles" ); // Adjust time zone to United States. DateTime dateTimeLos_Angeles = dateTimeUtc.withZone( timeZoneLos_Angeles ); 

调整到印度时区,比UTC早五个半小时。 请注意,对于线程安全, Joda-Time使用不可变对象 。 我们不是进行更改,而是在复制原始值时创建新实例。

 DateTimeZone timeZoneKolkata = DateTimeZone.forID( "Asia/Kolkata" ); // Adjust time zone to India. DateTime dateTimeKolkata = dateTimeLos_Angeles.withZone( timeZoneKolkata ); 

如果需要,转换回juDate。

 java.util.Date dateOut = dateTimeKolkata.toDate(); 

转储到控制台。 请注意,默认情况下,Joda-Time会根据ISO 8601标准创建字符串表示。

 System.out.println( "dateIn: " + dateIn ); // juDate's "toString" method applies JVM's default time zone. Very confusing, as a juDate has no time zone. System.out.println( "dateTimeUtc: " + dateTimeUtc ); System.out.println( "dateTimeLos_Angeles: " + dateTimeLos_Angeles ); System.out.println( "dateTimeKolkata: " + dateTimeKolkata ); System.out.println( "dateOut: " + dateOut ); // juDate's "toString" method uses a terrible format. Use only in a pinch like debugging, never in production. System.out.println( "Milliseconds since Unix epoch: " + dateIn.getTime() + " | " + dateTimeUtc.getMillis() + " | " + dateTimeLos_Angeles.getMillis() + " | " + dateTimeKolkata.getMillis() + " | " + dateOut.getTime() ); 

跑的时候……

 dateIn: Wed Jun 04 13:51:01 PDT 2014 dateTimeUtc: 2014-06-04T20:51:01.593Z dateTimeLos_Angeles: 2014-06-04T13:51:01.593-07:00 dateTimeKolkata: 2014-06-05T02:21:01.593+05:30 dateOut: Wed Jun 04 13:51:01 PDT 2014 Milliseconds since Unix epoch: 1401915061593 | 1401915061593 | 1401915061593 | 1401915061593 | 1401915061593 

了解所有这些日期时间值代表相同的同时时刻 ,即宇宙时间轴上的相同点。 请注意字符串在日期(6月4日和5日)之间的变化情况,但我们看到了相同的时刻。 想象一下雷克雅未克,洛杉矶和加尔各答的三个人都在同一时刻( 挂钟时间 )看着他们的怀表/手机。