用时区将Joda-Time`DateTime`转换为没有时区的DateTime?

mem*_*und 2 java datetime jodatime

给定一个DateTime例如2015-07-09T05:10:00+02:00使用乔达时间

如何将其转换为本地时间,即将时区添加到时间本身.期望的输出:2015-07-09T07:10:00

我试过dateTime.toDateTime(DateTimeZone.UTC)但是没有给出理想的结果.

Bas*_*que 12

在正确答案中添加更多信息和示例(接受的答案其他答案).

更新在java.time类的末尾添加了一节.这些取代了Joda-Time.

目的 LocalDateTime

你可能会对目的感到困惑LocalDateTime.

如果尝试使用"挂钟时间"来表示日期时间值,如某地方某人查看他们自己的时钟和日历所示,则调整DateTime对象的时区以适应所需的地点.

LocalDateTime不适用于特定地区,但适用于日期+时间的一般概念.例如,"今年的圣诞节将于2014年12月25日午夜开始".从概念上讲,这是一个LocalDateTime,旨在表示巴黎的不同时刻,而不是蒙特利尔和奥克兰.

调整时区

使用DateTimeZoneJoda-Time中的类调整到所需的时区.Joda-Time使用不可变对象.因此,我们不是更改时区("mutate"),而是基于旧的DateTime对象实例化,但具有所需的差异(某些其他时区).

使用适当的时区名称.一般一个continent/cityOrRegion.

DateTimeZone zoneParis = DateTimeZone.forID( "Europe/Paris" );
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTimeZone zoneAuckland = DateTimeZone.forID( "Pacific/Auckland" );
Run Code Online (Sandbox Code Playgroud)

解析字符串,指定时区,调整到其他时区.

DateTime dateTimeParis = new DateTime( "2015-07-09T05:10:00+02:00" , zoneParis );
DateTime dateTimeMontréal = dateTimeParis.withZone( zoneMontréal );
DateTime dateTimeAuckland = dateTimeParis.withZone( zoneAuckland );
Run Code Online (Sandbox Code Playgroud)

转储到控制台.

System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeAuckland: " + dateTimeAuckland );
Run Code Online (Sandbox Code Playgroud)

跑步时

dateTimeParis: 2015-07-09T05:10:00.000+02:00
dateTimeMontréal: 2015-07-08T23:10:00.000-04:00
dateTimeAuckland: 2015-07-09T15:10:00.000+12:00
Run Code Online (Sandbox Code Playgroud)

使用格式化字符串进行本地化

在创建日期时间对象的字符串表示时,Joda-Time可以转换为特定语言环境的语言和习惯样式.

DateTimeFormatter formatterMontréal = DateTimeFormat.forStyle( "FF" ).withZone( zoneMontréal ).withLocale( Locale.CANADA_FRENCH );
String outputMontréal = formatterMontréal.print( dateTimeParis );
System.out.println( "outputMontréal: " + outputMontréal );
Run Code Online (Sandbox Code Playgroud)

运行时:

outputMontréal: mercredi 8 juillet 2015 23 h 10 EDT
Run Code Online (Sandbox Code Playgroud)

java.time

现在处于维护模式Joda-Time项目建议迁移到java.time类.Joda-Time框架启发了java.time,因此概念非常相似.

ZoneId并且ZoneOffset是分别代表时区和从UTC偏移的两个类.偏移量仅为小时数,分钟数和秒数.时区是偏移量加上一组用于处理诸如夏令时(DST)等异常的规则.

ZoneId zoneParis = ZoneId.of( "Europe/Paris" );
ZoneId zoneMontreal = ZoneId.of( "America/Montreal" );
ZoneId zoneAuckland = ZoneId.of( "Pacific/Auckland" );
Run Code Online (Sandbox Code Playgroud)

java.time中的主要日期时间类是:

在解析/生成表示日期时间值的字符串时,java.time类默认使用ISO 8601标准格式.因此,无需使用此类输入指定格式设置模式.

此输入表示从UTC偏移但不是全时区.所以我们解析为一个OffsetDateTime而不是一个ZonedDateTime.

OffsetDateTime odt = OffsetDateTime.parse( "2015-07-09T05:10:00+02:00" );
Run Code Online (Sandbox Code Playgroud)

作为java.time的基本构建块,总是按照定义的UTC,你可能想要提取一个Instant.

Instant instant = odt.toInstant();  // `Instant` is always in UTC by definition.
Run Code Online (Sandbox Code Playgroud)

您可以调整为时区.

ZonedDateTime zdtParis = odt.atZoneSameInstant( zoneParis );
ZonedDateTime zdtMontreal = odt.atZoneSameInstant( zoneMontreal );
ZonedDateTime zdtAuckland = zdtMontreal.withZoneSameInstant( zoneAuckland );
Run Code Online (Sandbox Code Playgroud)

通过DateTimeFormatter课程本地化.

DateTimeFormatter f = DateTimeformatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH );
String output = zdtMontreal.format( f );
Run Code Online (Sandbox Code Playgroud)

请参阅IdeOne.com中的实时代码.

odt:2015-07-09T05:10 + 02:00

时刻:2015-07-09T03:10:00Z

zdtParis:2015-07-09T05:10 + 02:00 [欧洲/巴黎]

zdtMontreal:2015-07-08T23:10-04:00 [美国/蒙特利尔]

zdtAuckland:2015-07-09T15:10 + 12:00 [太平洋/奥克兰]

输出:mercredi 8 juillet 2015 23 h 10 EDT


关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

从哪里获取java.time类?

ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.


Paw*_*ski 8

@Nazgul说的是对的,但是如果你想要实现的只是UTC区域的"壁垒时间",你可以做类似的事情:

DateTime dateTimePlus2 = DateTime.parse("2015-07-09T05:10:00+02:00");
System.out.println(dateTimePlus2);

DateTime dateTimeUTC = dateTimePlus2.withZone(DateTimeZone.UTC);
System.out.println(dateTimeUTC);

LocalDateTime localDateTimeUTC = dateTimeUTC.toLocalDateTime();
System.out.println(localDateTimeUTC);
Run Code Online (Sandbox Code Playgroud)

结果:

2015-07-09T05:10:00.000+02:00
2015-07-09T03:10:00.000Z        ("Z" == Zulu tz == UTC)
2015-07-09T03:10:00.000
Run Code Online (Sandbox Code Playgroud)

如您所见,时间不是您预期的"07:10",因为UTC + 2区域 UTC 两个小时.转换为UTC 减去 2小时.