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
Convert Joda-Time `DateTime` with timezone to DateTime without timezone?
提问by membersound
Given a DateTime
for example 2015-07-09T05:10:00+02:00
using 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 DateTime
object 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 DateTimeZone
class 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).
使用DateTimeZone
Joda-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,因此概念非常相似。
ZoneId
and ZoneOffset
are 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).
ZoneId
和ZoneOffset
是分别代表时区和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 中的主要日期时间类是:
Instant
– A moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).OffsetDateTime
– AnInstant
plus aZoneOffset
.ZonedDateTime
– AnInstant
plus aZoneId
.
Instant
– UTC时间线上的一个时刻,分辨率为纳秒(最多九 (9) 位小数)。OffsetDateTime
–Instant
加一个ZoneOffset
。ZonedDateTime
–Instant
加一个ZoneId
。
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 OffsetDateTime
rather 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 DateTimeFormatter
class.
通过DateTimeFormatter
类本地化。
DateTimeFormatter f = DateTimeformatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH );
String output = zdtMontreal.format( f );
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 类?
- Java SE 8and SE 9and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABPproject adapts ThreeTen-Backport(mentioned above) for Android specifically.
- See How to use….
- Java SE 8和SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 所述ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅如何使用......。
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 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。