Java 将带时区的 Joda-Time `DateTime` 转换为不带时区的 DateTime?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27381626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:16:10  来源:igfitidea点击:

Convert Joda-Time `DateTime` with timezone to DateTime without timezone?

javadatetimejodatime

提问by membersound

Given a DateTimefor example 2015-07-09T05:10:00+02:00using Joda-Time?

给定一个使用Joda-Time 的DateTime例子?2015-07-09T05:10:00+02:00

How can I convert it to local time, meaning adding the timezone to the time itself. Desired output: 2015-07-09T07:10:00

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

I tried dateTime.toDateTime(DateTimeZone.UTC)but that did not give the desired result.

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

采纳答案by Pawe? Wyrwiński

What @Nazgul said is right, but in case all you want to achieve is a "wall-time" in UTC zone you can do something like that:

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

Result:

结果:

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

As you can see, the time is not "07:10" as you expected, because UTC+2 zone is two hours aheadof UTC. Converting to UTC subtracts2 hours.

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

回答by Nazgul

DateTime without timezone dosnt make sense. DateTime are always relative to the timezone in which they are used. Without the timezone information a date time combination makes no sense for the geography as such. raw timestamp millies can however be accessed as the number of millies gone since 1st Jan 1970 but any concrete date time combinations must have a timezone with it.

没有时区的 DateTime 没有意义。DateTime 总是相对于使用它们的时区。如果没有时区信息,日期时间组合对于地理而言毫无意义。然而,原始时间戳毫秒数可以作为自 1970 年 1 月 1 日以来消失的毫秒数来访问,但任何具体的日期时间组合都必须有一个时区。

回答by Basil Bourque

Adding a bit more info and examples to the correct answers (accepted answerand other one).

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

UPDATEAdded section at end on java.time classes. These supplant Joda-Time.

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

Purpose of LocalDateTime

目的 LocalDateTime

You may be confused about the purpose of LocalDateTime.

您可能对 的目的感到困惑LocalDateTime

If trying to represent a date-time value using "wall clock time" as seen by someone in a locality looking at their own clock and calendar, then adjust the time zone of the DateTimeobject to suit the desired locality.

如果尝试使用“挂钟时间”表示日期时间值,如当地某人查看自己的时钟和日历时所看到的,则调整DateTime对象的时区以适合所需的地点。

LocalDateTime is not meant for a particular locality but for the general idea of date+time. For example, "This year's Christmas starts at midnight on December 25, 2014". Conceptually, that is a LocalDateTime, intended to mean different moments in Paris than Montréal and Auckland.

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

Adjusting Time Zone

调整时区

Use the DateTimeZoneclass in Joda-Time to adjust to a desired time zone. Joda-Time uses immutable objects. So rather than change the time zone ("mutate"), we instantiate a new DateTime object based on the old but with the desired difference (some other time zone).

使用DateTimeZoneJoda-Time 中的类来调整到所需的时区。Joda-Time 使用不可变对象。因此,我们不是更改时区(“mutate”),而是根据旧的但具有所需差异(其他时区)实例化一个新的 DateTime 对象。

Use proper time zone names. Generally a continent/cityOrRegion.

使用正确的时区名称。一般一个continent/cityOrRegion.

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

Parse string, assign a time zone, adjust to other time zones.

解析字符串,分配时区,调整到其他时区。

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

Dump to console.

转储到控制台。

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

When run.

跑的时候。

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 can translate to a particular locale's language and customary style when creating a string representation of your date-time object.

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

When run:

运行时:

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


java.time

时间

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses. The Joda-Time framework inspired java.time, so concepts are quite similar.

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

ZoneIdand ZoneOffsetare the two classes to represent a time zone and offset-from-UTCrespectively. An offset is merely a number of hours and minutes and seconds. A time zone is an offset plusa set of rules for handling anomalies such as Daylight Saving Time (DST).

ZoneIdZoneOffset是分别代表时区和UTC偏移量的两个类。偏移量只是一些小时、分钟和秒。时区是偏移量加上一组用于处理夏令时 (DST) 等异常的规则。

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

The primary date-time classes in java.time are:

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

The java.time classes use ISO 8601standard formats by default when parsing/generating strings representing date-time values. So no need to specify a formatting pattern with such inputs.

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

This input here indicates an offset-from-UTCbut not a full time zone. So we parse as an OffsetDateTimerather than a ZonedDateTime.

此处的此输入表示与 UTC偏移量,但不是完整时区。所以我们解析为 anOffsetDateTime而不是 a ZonedDateTime

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

As the basic building-block of java.time, always in UTCby definition, you may want to extract an Instant.

作为 java.time 的基本构建块,根据定义始终采用UTC,您可能希望提取一个Instant.

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

You can adjust into a time zone.

您可以调整到时区。

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

Localize via the DateTimeFormatterclass.

通过DateTimeFormatter类本地化。

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

See live code in IdeOne.com.

在 IdeOne.com 中查看实时代码

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

instant: 2015-07-09T03:10:00Z

zdtParis: 2015-07-09T05:10+02:00[Europe/Paris]

zdtMontreal: 2015-07-08T23:10-04:00[America/Montreal]

zdtAuckland: 2015-07-09T15:10+12:00[Pacific/Auckland]

output: mercredi 8 juillet 2015 23 h 10 EDT

时间:2015-07-09T05:10+02:00

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

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

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

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

输出:mercredi 8 juillet 2015 23 h 10 EDT



About java.time

关于 java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

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

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

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

Where to obtain the java.time classes?

从哪里获得 java.time 类?

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多