用时区将Joda-Time`DateTime`转换为没有时区的DateTime?
给定DateTime
例如2015-07-09T05:10:00+02:00
使用Joda-Time ?
如何将其转换为本地时间,即将时区添加到时间本身。 期望的输出: 2015-07-09T07:10:00
我尝试了dateTime.toDateTime(DateTimeZone.UTC)
但没有给出所需的结果。
@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小时。
在正确答案中添加更多信息和示例( 接受的答案和其他 答案 )。
更新在java.time类的末尾添加了一节。 这些取代了Joda-Time。
LocalDateTime
目的
您可能会对LocalDateTime
的用途感到困惑。
如果尝试使用“挂钟时间”来表示日期时间值,就像当地人看到他们自己的时钟和日历一样,那么调整DateTime
对象的时区以适应所需的位置。
LocalDateTime不适用于特定地点,但适用于日期+时间的一般概念。 例如,“今年的圣诞节将于2014年12月25日午夜开始”。 从概念上讲,这是一个LocalDateTime,旨在表示巴黎的不同时刻,而不是蒙特利尔和奥克兰。
调整时区
使用Joda-Time中的DateTimeZone
类调整到所需的时区。 Joda-Time使用不可变对象。 因此,我们不是更改时区(“mutate”),而是基于旧的Date实例化实例化,但具有所需的差异(某些其他时区)。
使用适当的时区名称 。 一般来说是一个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
使用格式化字符串进行本地化
在创建日期时间对象的字符串表示时,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-Time项目建议迁移到java.time类。 Joda-Time框架启发了java.time,因此概念非常相似。
ZoneId
和ZoneOffset
分别代表时区和UTC的偏移量 。 偏移量仅为小时数,分钟数和秒数。 时区是偏移量加上一组用于处理夏令时(DST)等exception的规则。
ZoneId zoneParis = ZoneId.of( "Europe/Paris" ); ZoneId zoneMontreal = ZoneId.of( "America/Montreal" ); ZoneId zoneAuckland = ZoneId.of( "Pacific/Auckland" );
java.time中的主要日期时间类是:
-
Instant
– UTC时间轴上的一个时刻,分辨率为纳秒 (最多九(9)位小数)。 -
OffsetDateTime
– 一个Instant
加一个ZoneOffset
。 -
ZonedDateTime
– 一个Instant
加一个ZoneId
。
在解析/生成表示日期时间值的字符串时,java.time类默认使用ISO 8601标准格式。 因此,无需使用此类输入指定格式设置模式。
此输入指示与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 );
查看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类?
- Java SE 8和SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和SE 7
- 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
- Android的
- ThreeTenABP项目特别适用于Android的ThreeTen-Backport (如上所述)。
- 请参阅如何使用….
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如Interval
, YearWeek
, YearQuarter
等。
没有时区dosnt的DateTime是有道理的。 DateTime始终相对于使用它们的时区。 没有时区信息,日期时间组合对地理位置没有意义。 然而,原始时间戳毫秒可以作为自1970年1月1日以来的毫秒数而被访问,但任何具体的日期时间组合必须具有时区。