ThreeTenABP:DateTimeParseException

时间:2018-12-18 17:44:22

标签: android date datetime threetenbp

尝试更改字符串的日期格式,但获取DateTimeException:

String oldDate = "2018-12-18T17:04:56+00:00";
String outputFormat = "DD-MM";
try {
    Instant instant = Instant.parse(oldDate);
    LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
    return localDateTime.format(DateTimeFormatter.ofPattern(outputFormat);
} catch (DateTimeException | IllegalArgumentException e) {
    Log.e("Error", e.getLocalizedMessage());
    return "";
}

我遇到的错误是: 无法在索引19处解析文本'2018-12-18T17:04:56 + 00:00'

我正在使用com.jakewharton.threetenabp:threetenabp:1.1.1,因为我无法使用Java 8类

1 个答案:

答案 0 :(得分:3)

tl; dr

OffsetDateTime.parse(                // Represent a moment, a date with time-of-day in the context of an offset-from-UTC (some number of hours-minutes-seconds).
    "2018-12-18T17:04:56+00:00"      // Input string in standard ISO 8601 format, with an indicator of an offset-from-UTC of zero hours and zero minutes, meaning UTC itself.
)                                    // Returns an `OffsetDateTime` object.
.atZoneSameInstant(                  // Adjust our moment from UTC to the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.systemDefault()           // Using the JVM’s current default time zone. NOTE: this default can change at any moment during runtime. If important, confirm with the user.
)                                    // Returns a `ZonedDateTime` object.
.toString()                          // Generate text in standard ISO 8601 format wisely extended by appending the name of the zone in square brackets. Returns a `String` object.
  

2018-12-18T09:04:56-08:00 [美国/洛杉矶]

详细信息

以下是使用ThreeTen-Backport项目的示例Java代码,对于{26}之前的Android,该项目由ThreeTenABP进行了扩展。

import org.threeten.bp.*;

格式错误

Instant.parse命令使用DateTimeFormatter.ISO_INSTANT格式化程序。该格式化程序期望最后一个Z表示UTC。

Instant类是 java.time 框架的基本构建模块类。要获得更大的灵活性,请使用OffsetDateTime。其默认格式化程序DateTimeFormatter.ISO_OFFSET_DATE_TIME可以处理您的输入。

String input = "2018-12-18T17:04:56+00:00";
OffsetDateTime odt = OffsetDateTime.parse( input );
  

odt.toString():2018-12-18T17:04:56Z

班级错误

请勿使用LocalDateTime来跟踪时刻。该类故意缺少任何time zoneoffset-from-UTC的概念。它只是一个日期和一个时间。因此,它不能表示时刻,而不是时间轴上的一点。相反,此类表示在26-27小时(全球时区范围)内的潜在时刻。

要跟踪时刻,请仅使用:

  • Instant
    在UTC中停留片刻,始终是UTC。
  • OffsetDateTime
    日期,一天中的时间,与UTC偏移。偏移量仅是数小时-分-秒,仅此而已。
  • ZonedDateTime
    通过特定地区的人(时区)的挂钟时间看到的时刻。区域是特定区域使用的偏移的过去,现在和将来的历史记录。

要将我们的OffsetDateTime从UTC调整到某个时区,请应用ZoneId以获得ZonedDateTime

ZoneId z = ZoneId.systemDefault() ;  // If important, confirm the zone with user rather than depending on the JVM’s current default zone.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
  

zdt.toString():2018-12-18T09:04:56-08:00 [America / Los_Angeles]

有了这些结果,我们看到在北美大部分西海岸,UTC下午5点同时是上午9点。 -08:00的不同意味着在该日期,西海岸比世界标准时间晚了八个小时。


关于 java.time

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

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

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

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

在哪里获取java.time类?

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