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

问题描述 投票:2回答:3

给出DateTime例如使用2015-07-09T05:10:00+02:00Joda-Time

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

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

java datetime jodatime
3个回答
7
投票

@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);

结果:

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

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


12
投票

在正确答案中添加更多信息和示例(accepted answerother one)。

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

Purpose of LocalDateTime

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

如果尝试使用“挂钟时间”来表示日期时间值,就像当地人看到他们自己的时钟和日历一样,那么调整DateTime对象的时区以适应所需的位置。

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

Adjusting Time Zone

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

使用适当的time zone names。一般是continent/cityOrRegion

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

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

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

转储到控制台。

System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );
System.out.println( "dateTimeAuckland: " + dateTimeAuckland );

跑步时

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

Localize Using Formatted Strings

在创建日期时间对象的字符串表示时,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 );

运行时:

outputMontréal: mercredi 8 juillet 2015 23 h 10 EDT

java.time

现在在Joda-Timemaintenance mode项目建议迁移到java.time班。 Joda-Time框架启发了java.time,因此概念非常相似。

ZoneIdZoneOffset分别代表时区和offset-from-UTC。偏移量仅为小时数,分钟数和秒数。时区是偏移量加上一组用于处理诸如夏令时(DST)等异常的规则。

ZoneId zoneParis = ZoneId.of( "Europe/Paris" );
ZoneId zoneMontreal = ZoneId.of( "America/Montreal" );
ZoneId zoneAuckland = ZoneId.of( "Pacific/Auckland" );

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

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

此输入表示offset-from-UTC但不是全时区。所以我们解析为OffsetDateTime而不是ZonedDateTime

OffsetDateTime odt = OffsetDateTime.parse( "2015-07-09T05:10:00+02:00" );

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

Instant instant = odt.toInstant();  // `Instant` is always in UTC by definition.

您可以调整为时区。

ZonedDateTime zdtParis = odt.atZoneSameInstant( zoneParis );
ZonedDateTime zdtMontreal = odt.atZoneSameInstant( zoneMontreal );
ZonedDateTime zdtAuckland = zdtMontreal.withZoneSameInstant( zoneAuckland );

通过DateTimeFormatter课程进行本地化。

DateTimeFormatter f = DateTimeformatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH );
String output = zdtMontreal.format( f );

live code in IdeOne.com

来自: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 [太平洋/奥克兰]

输出:2015年7月8日星期三美国东部时间23:10


About java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.DateCalendarSimpleDateFormat

现在在Joda-Timemaintenance mode项目建议迁移到java.time班。

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

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。你可能会在这里找到一些有用的类,如IntervalYearWeekYearQuartermore


0
投票

没有时区dosnt的DateTime是有道理的。 DateTime始终相对于使用它们的时区。没有时区信息,日期时间组合对地理位置没有意义。然而,原始时间戳毫秒可以作为自1970年1月1日以来的毫秒数而被访问,但任何具体的日期时间组合必须具有时区。

© www.soinside.com 2019 - 2024. All rights reserved.