给出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小时。
在正确答案中添加更多信息和示例(accepted answer和other one)。
更新在java.time类的末尾添加了一节。这些取代了Joda-Time。
LocalDateTime
你可能会对LocalDateTime
的目的感到困惑。
如果尝试使用“挂钟时间”来表示日期时间值,就像当地人看到他们自己的时钟和日历一样,那么调整DateTime
对象的时区以适应所需的位置。
LocalDateTime不适用于特定地区,但适用于日期+时间的一般概念。例如,“今年的圣诞节将于2014年12月25日午夜开始”。从概念上讲,这是一个LocalDateTime,旨在表示巴黎的不同时刻,而不是蒙特利尔和奥克兰。
使用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
在创建日期时间对象的字符串表示时,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
现在在Joda-Time的maintenance mode项目建议迁移到java.time班。 Joda-Time框架启发了java.time,因此概念非常相似。
ZoneId
和ZoneOffset
分别代表时区和offset-from-UTC。偏移量仅为小时数,分钟数和秒数。时区是偏移量加上一组用于处理诸如夏令时(DST)等异常的规则。
ZoneId zoneParis = ZoneId.of( "Europe/Paris" );
ZoneId zoneMontreal = ZoneId.of( "America/Montreal" );
ZoneId zoneAuckland = ZoneId.of( "Pacific/Auckland" );
java.time中的主要日期时间类是:
Instant
- UTC时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。OffsetDateTime
- 一个Instant
加上ZoneOffset
。ZonedDateTime
- 一个Instant
加上ZoneId
。在解析/生成表示日期时间值的字符串时,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 );
来自: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
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.Date
,Calendar
和SimpleDateFormat
。
现在在Joda-Time的maintenance mode项目建议迁移到java.time班。
要了解更多信息,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。你可能会在这里找到一些有用的类,如Interval
,YearWeek
,YearQuarter
和more。
没有时区dosnt的DateTime是有道理的。 DateTime始终相对于使用它们的时区。没有时区信息,日期时间组合对地理位置没有意义。然而,原始时间戳毫秒可以作为自1970年1月1日以来的毫秒数而被访问,但任何具体的日期时间组合必须具有时区。