lde*_*may 1 java android date simpledateformat timestamp-with-timezone
假设我的设备在澳大利亚(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));
Run Code Online (Sandbox Code Playgroud)
但是不幸的是,我找不到一种显示日期的干净方法:
sdf.format(cal.getTime());
Run Code Online (Sandbox Code Playgroud)
使用设备时区。
因此,我“手动”解析了日期以提取时区以将其设置在日历中。
cal.setTimeZone(TimeZone.getTimeZone("GMT" + date.substring(date.length() - 6, date.length())));
Run Code Online (Sandbox Code Playgroud)
但这似乎并不能解决问题。
我怎样才能做到这一点?
在原始时区(GMT + 02:00)。
不,不正确。文本GMT+02:00表示相对于UTC的偏移量,而不是时区。时区是一个偏移量,外加一组用于处理异常的规则,例如夏令时(DST)。
时区以continent/region诸如America/Montreal或的格式命名Asia/Kolkata。始终使用这些专有名称。永远不要在主流媒体中看到3-4个缩写;这些既不是标准化的也不是唯一的。
事实证明,与最早的Java版本捆绑在一起的旧的日期时间类设计不佳,令人困惑且麻烦。避免他们。这些类被非常成功的Joda-Time库及其后继的java.time框架所取代。
该java.time框架内置的Java 8和更高版本。它的许多功能在ThreeTen-Backport项目中都已反向移植到Java 6和7 ,并在ThreeTenABP中进一步适应了Android 。
在Oracle教程中了解更多信息。
OffsetDateTime输入字符串仅具有与UTC的偏移量,而没有整个时区。因此,我们使用OffsetDateTime类来表示这种价值。
幸运的是,您输入的字符串为标准ISO 8601格式。解析/生成日期时间值的文本表示时,java.time类默认使用ISO 8601格式。因此,我们可以直接解析而无需费心定义格式设置模式。
String input = "2016-04-22T17:45:00+02:00";
OffsetDateTime odt = OffsetDateTime.parse( input );
Run Code Online (Sandbox Code Playgroud)
调用OffsetDateTime::toString()以生成相同格式的字符串。
String output = odt.toString(); // ISO 8601 formatted string.
Run Code Online (Sandbox Code Playgroud)
Instant程序员不应该考虑这种本地日期时间。通常,您应该在UTC中进行业务逻辑,数据库存储和数据交换。
在java.time中,an Instant表示UTC时间轴上的时刻,分辨率为纳秒。我们可以提取Instant从我们的OffsetDateTime。
Instant instant = odt.toInstant();
Run Code Online (Sandbox Code Playgroud)
ZonedDateTime由于使用了诸如夏令时之类的异常处理规则,使用时区总是比仅使用偏移更好。
您可以轻松地调整或者一个Instant或OffsetDateTime通过施加到一个时区ZoneId得到ZonedDateTime。有关更多讨论,请参见我的较长答案和关于在这些类之间进行转换/调整的一般主题的图表。
ZoneId zoneId_Montreal = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId_Montreal );
Run Code Online (Sandbox Code Playgroud)
…要么…
ZonedDateTime zdt_Montreal = odt.atZoneSameInstant( zoneId_Montreal );
Run Code Online (Sandbox Code Playgroud)
请注意,在应用时区时,您可能会看到一天中的时间甚至日期发生变化。可能需要根据该区域的规则进行调整,以适应夏令时(DST)或其他问题。
您可以进一步调整到其他时区。你提到澳大利亚。该国家/地区有很多时区,因此您必须选择适合您(或您的用户)的时区,因为它们现在或过去或将来可能有不同的规则。
ZoneId zoneId_Melbourne = ZoneId.of( "Australia/Melbourne" );
ZonedDateTime zdt_Melbourne = zdt_Montreal.withZoneSameInstant( zoneId_Melbourne );
Run Code Online (Sandbox Code Playgroud)
在调用ZonedDateTime::toString该方法时,您会注意到,该方法通过在方括号中附加时区名称来扩展标准ISO 8601格式。
要生成其他格式的字符串,请在Stack Overflow中搜索java.time.format和的主题DateTimeFormatter。这些ofLocalized…方法与一起Locale可以自动本地化格式,包括翻译人类语言的日期/月份名称,并遵循元素顺序,句点对逗号等的文化规范。
该java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*
在哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter,和更多。
| 归档时间: |
|
| 查看次数: |
2018 次 |
| 最近记录: |