如何使用 DateFormatter 将格式为 yyyyMMddHHmmss 的 DateTime 解析为 OffsetDateTime
How to parse DateTime in format yyyyMMddHHmmss to OffsetDateTime using DateFormatter
我有一个 API 用于 JSON 解析,它需要 DateTimeFormatter 实例才能将日期时间字符串解析为 OffsetDateTime。但是我总是遇到异常 无法从 TemporalAccessor 获取 ZoneOffset:{},ISO 解析为 java.time.format.Parsed 类型的 2021-08-17T13:26:49
API 使用 OffsetDateTime.parse(String, DateFormatter).
// DateTimeFormatter instance to be provided to the API
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
// this is how the API uses the DateTimeFormatter instance
OffsetDateTime dateTime = OffsetDateTime.parse("20210817132649", formatter);
我必须如何创建 DateTimeFormatter 才能提供 ZoneOffset,以便 API 能够正确解析 DateTime。 ZoneOffset 可能是 UTC。
更新
我从你那里了解到你正在使用 API 如下:
apiClient.getJSON().setOffsetDateTimeFormat(DateTimeFormatter);
并且您没有传递时区信息的参数。在这种情况下,您可以使用 DateTimeFormatter#withZone
如下所示:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
.withZone(ZoneOffset.UTC);
OffsetDateTime odt = OffsetDateTime.parse("20210817132649", formatter);
System.out.println(odt);
}
}
输出:
2021-08-17T13:26:49Z
即现在,您的电话是:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
.withZone(ZoneOffset.UTC);
apiClient.getJSON().setOffsetDateTimeFormat(formatter);
原回答
您的日期时间字符串没有时区偏差。将其解析为 LocalDateTime
,然后对其应用偏移量。
演示:
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH);
OffsetDateTime odt = LocalDateTime.parse("20210817132649", formatter)
.atOffset(ZoneOffset.UTC);
System.out.println(odt);
}
}
输出:
2021-08-17T13:26:49Z
输出中的 Z
是零时区偏移量的 timezone designator。它代表 Zulu 并指定 Etc/UTC
时区(时区偏移量为 +00:00
小时)。您可以根据您的要求指定不同的时区偏移量(例如 ZoneOffset.of("+05:30")
)。
如果您有 ZoneId
可用
如果您有 ZoneId
可用,您应该将给定的日期时间字符串解析为 LocalDateTime
,然后将 ZoneId
应用于它以获得 ZonedDateTime
您总能从中获得 OffsetDateTime
。 ZonedDateTime
最好的一点是它被设计为自动调整时区偏移量,而 OffsetDateTime
用于表示固定的时区偏移量。
演示:
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH);
ZonedDateTime zdt = LocalDateTime.parse("20210817132649", formatter)
.atZone(ZoneId.of("Etc/UTC"));
OffsetDateTime odt = zdt.toOffsetDateTime();
System.out.println(odt);
}
}
输出:
2021-08-17T13:26:49Z
您可以根据需要指定不同的 ZoneId
(例如 ZoneId.of("Asia/Kolkata")
)。
详细了解 modern Date-Time API* from Trail: Date Time。
* 如果您正在为一个 Android 项目工作并且您的 Android API 水平仍然不符合 Java-8,检查Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time
。
最好使用 ZonedDateTime
- 区别在于夏令时和具有相同时区偏移的国家/地区。也许使用默认 ZoneId
.
嗯,您传入的字符串不包含区域信息,而 OffsetDateTime
需要区域信息。
因此您必须为其设置一个值。
您可以使用 DateTimeFormatterBuilder
class,如果解析信息中缺少某个字段,则可以指示它使用一些默认值:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.appendPattern("yyyyMMddHHmmss")
.toFormatter(Locale.ROOT);
您也可以直接将隐含区域设置为 DateTimeFormatter
:
DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC);
我有一个 API 用于 JSON 解析,它需要 DateTimeFormatter 实例才能将日期时间字符串解析为 OffsetDateTime。但是我总是遇到异常 无法从 TemporalAccessor 获取 ZoneOffset:{},ISO 解析为 java.time.format.Parsed 类型的 2021-08-17T13:26:49 API 使用 OffsetDateTime.parse(String, DateFormatter).
// DateTimeFormatter instance to be provided to the API
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
// this is how the API uses the DateTimeFormatter instance
OffsetDateTime dateTime = OffsetDateTime.parse("20210817132649", formatter);
我必须如何创建 DateTimeFormatter 才能提供 ZoneOffset,以便 API 能够正确解析 DateTime。 ZoneOffset 可能是 UTC。
更新
我从你那里了解到你正在使用 API 如下:
apiClient.getJSON().setOffsetDateTimeFormat(DateTimeFormatter);
并且您没有传递时区信息的参数。在这种情况下,您可以使用 DateTimeFormatter#withZone
如下所示:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
.withZone(ZoneOffset.UTC);
OffsetDateTime odt = OffsetDateTime.parse("20210817132649", formatter);
System.out.println(odt);
}
}
输出:
2021-08-17T13:26:49Z
即现在,您的电话是:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
.withZone(ZoneOffset.UTC);
apiClient.getJSON().setOffsetDateTimeFormat(formatter);
原回答
您的日期时间字符串没有时区偏差。将其解析为 LocalDateTime
,然后对其应用偏移量。
演示:
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH);
OffsetDateTime odt = LocalDateTime.parse("20210817132649", formatter)
.atOffset(ZoneOffset.UTC);
System.out.println(odt);
}
}
输出:
2021-08-17T13:26:49Z
输出中的 Z
是零时区偏移量的 timezone designator。它代表 Zulu 并指定 Etc/UTC
时区(时区偏移量为 +00:00
小时)。您可以根据您的要求指定不同的时区偏移量(例如 ZoneOffset.of("+05:30")
)。
如果您有 ZoneId
可用
如果您有 ZoneId
可用,您应该将给定的日期时间字符串解析为 LocalDateTime
,然后将 ZoneId
应用于它以获得 ZonedDateTime
您总能从中获得 OffsetDateTime
。 ZonedDateTime
最好的一点是它被设计为自动调整时区偏移量,而 OffsetDateTime
用于表示固定的时区偏移量。
演示:
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH);
ZonedDateTime zdt = LocalDateTime.parse("20210817132649", formatter)
.atZone(ZoneId.of("Etc/UTC"));
OffsetDateTime odt = zdt.toOffsetDateTime();
System.out.println(odt);
}
}
输出:
2021-08-17T13:26:49Z
您可以根据需要指定不同的 ZoneId
(例如 ZoneId.of("Asia/Kolkata")
)。
详细了解 modern Date-Time API* from Trail: Date Time。
* 如果您正在为一个 Android 项目工作并且您的 Android API 水平仍然不符合 Java-8,检查Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time
。
最好使用 ZonedDateTime
- 区别在于夏令时和具有相同时区偏移的国家/地区。也许使用默认 ZoneId
.
嗯,您传入的字符串不包含区域信息,而 OffsetDateTime
需要区域信息。
因此您必须为其设置一个值。
您可以使用 DateTimeFormatterBuilder
class,如果解析信息中缺少某个字段,则可以指示它使用一些默认值:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.appendPattern("yyyyMMddHHmmss")
.toFormatter(Locale.ROOT);
您也可以直接将隐含区域设置为 DateTimeFormatter
:
DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC);