gpt4 book ai didi

java - 以原始时区打印日期

转载 作者:行者123 更新时间:2023-11-29 06:54:46 25 4
gpt4 key购买 nike

假设我的设备在澳大利亚(GMT + 10:00)。

我有一个从API收到的日期“ 2016-04-22T17:45:00 + 02:00”。

我想在原始时区(GMT + 02:00)很好地显示它。

因此,我将SimpleDateFormat与“ yyyy-MM-dd'T'HH:mm:ssZZZZZ”一起使用。

String date = "2016-04-22T17:45:00+02:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ");
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(date));


但是不幸的是,我找不到一种显示日期的干净方法:

sdf.format(cal.getTime());


使用设备时区。

因此,我“手动”解析了日期以提取时区以将其设置在日历中。

cal.setTimeZone(TimeZone.getTimeZone("GMT" + date.substring(date.length() - 6, date.length())));


但这似乎并不能解决问题。

我怎样才能做到这一点?

最佳答案

时区=偏移量+规则


  在原始时区(GMT + 02:00)。


不,不正确。文本GMT+02:00表示offset-from-UTC,而不是时区。时区是一个偏移量,外加一组用于处理异常的规则,例如夏令时(DST)。

时区以continent/region格式命名,例如America/MontrealAsia/Kolkata。始终使用these proper names。永远不要在主流媒体中看到3-4个缩写;这些既不是标准化的也不是唯一的。

实际上,UTC是新的GMT

避免使用旧的日期时间类

事实证明,与最早的Java版本捆绑在一起的旧的日期时间类设计不佳,令人困惑且麻烦。避免他们。这些类被非常成功的Joda-Time库及其后继的java.time框架所取代。

java.time框架内置在Java 8 and later中。它的大部分功能在ThreeTen-Backport项目中都已移植回Java 6和7,并在ThreeTenABP中进一步适用于Android。

Oracle Tutorial中了解更多信息。

OffsetDateTime

输入字符串仅具有与UTC的偏移量,没有完整的time zone。因此,我们使用OffsetDateTime类表示此类值。

幸运的是,您输入的字符串为标准ISO 8601格式。解析/生成日期时间值的文本表示时,java.time类默认使用ISO 8601格式。因此,我们可以直接解析而无需费心定义格式设置模式。

String input = "2016-04-22T17:45:00+02:00";
OffsetDateTime odt = OffsetDateTime.parse( input );


调用 OffsetDateTime::toString()以生成相同格式的字符串。

String output = odt.toString(); // ISO 8601 formatted string.


Instant

程序员不应该考虑这种本地日期时间。通常,您应该在 UTC中进行业务逻辑,数据库存储和数据交换。

在java.time中, Instant表示UTC时间轴上的时刻,分辨率为 nanoseconds。我们可以从 Instant中提取一个 OffsetDateTime

Instant instant = odt.toInstant();


ZonedDateTime

由于使用了诸如夏令时之类的异常处理规则,使用时区总是比仅使用偏移更好。

通过应用 Instant获取 OffsetDateTime,您可以轻松地将 ZoneIdZonedDateTime调整到时区。有关更多讨论,请参见 my longer answerdiagram有关在这些类之间进行转换/调整的一般主题。

ZoneId zoneId_Montreal = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId_Montreal );


…要么…

ZonedDateTime zdt_Montreal = odt.atZoneSameInstant( zoneId_Montreal );


请注意,在应用时区时,您可能会看到一天中的时间甚至日期发生变化。可能需要根据该区域的规则进行调整,以适应 Daylight Saving Time (DST)或其他问题。

您可以进一步调整到其他时区。你提到澳大利亚。该国家/地区有很多时区,因此您必须选择适合您(或您的用户)的时区,因为它们现在或过去或将来可能有不同的规则。

ZoneId zoneId_Melbourne = ZoneId.of( "Australia/Melbourne" );
ZonedDateTime zdt_Melbourne = zdt_Montreal.withZoneSameInstant( zoneId_Melbourne );


您将在调用 ZonedDateTime::toString时注意到,该方法通过将时区的名称附加在方括号中来扩展标准ISO 8601格式。

要生成其他格式的字符串,请在Stack Overflow中搜索 java.time.formatDateTimeFormatter主题。 ofLocalized…方法与 Locale一起可以自动本地化格式,包括翻译人类语言的日期/月份名称,以及遵循文化规范的元素顺序,句点与逗号等。



关于java.time

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

现在位于 Joda-Time中的 maintenance mode项目建议迁移到 java.time类。

要了解更多信息,请参见 Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为 JSR 310

您可以直接与数据库交换java.time对象。使用与 JDBC driver或更高版本兼容的 JDBC 4.2。不需要字符串,不需要 java.sql.*类。

在哪里获取java.time类?


Java SE 8Java SE 9和更高版本


内置的
标准Java API的一部分,具有捆绑的实现。
Java 9添加了一些次要功能和修复。

Java SE 6Java SE 7


ThreeTen-Backport中的大部分java.time功能都已反向移植到Java 6和7。

Android


更高版本的Android捆绑了java.time类的实现。
对于早期的Android, ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参见 How to use ThreeTenABP…



ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如 IntervalYearWeekYearQuartermore

关于java - 以原始时区打印日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36736174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com