[英]How to parse DateTime in format yyyyMMddHHmmss to OffsetDateTime using DateFormatter
I have an API for JSON parsing which requires a DateTimeFormatter instance in order to parse date time strings to OffsetDateTime.我有一个用于 JSON 解析的 API,它需要一个 DateTimeFormatter 实例才能将日期时间字符串解析为 OffsetDateTime。 However I always get an exception Unable to obtain ZoneOffset from TemporalAccessor: {},ISO resolved to 2021-08-17T13:26:49 of type java.time.format.Parsed The API uses OffsetDateTime.parse(String, DateFormatter).但是我总是得到一个异常Unable to get ZoneOffset from TemporalAccessor: {},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);
How do I have to create the DateTimeFormatter in order to deliver a ZoneOffset, so that the API is able to parse the DateTime correctly.我必须如何创建 DateTimeFormatter 才能提供 ZoneOffset,以便 API 能够正确解析 DateTime。 The ZoneOffset may be UTC. ZoneOffset 可以是 UTC。
I understood from you that you are using the API as follows:我从您那里了解到您使用的 API 如下:
apiClient.getJSON().setOffsetDateTimeFormat(DateTimeFormatter);
and you do not have a parameter to pass timezone information.并且您没有传递时区信息的参数。 In this case, you can use DateTimeFormatter#withZone
as shown below:在这种情况下,您可以使用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);
}
}
Output:输出:
2021-08-17T13:26:49Z
ie now, your call will be:即现在,您的电话将是:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ENGLISH)
.withZone(ZoneOffset.UTC);
apiClient.getJSON().setOffsetDateTimeFormat(formatter);
Your date-time string does not have a timezone offset.您的日期时间字符串没有时区偏移量。 Parse it into a LocalDateTime
and then apply the offset to it.将其解析为LocalDateTime
,然后对其应用偏移量。
Demo:演示:
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);
}
}
Output:输出:
2021-08-17T13:26:49Z
The Z
in the output is the timezone designator for zero-timezone offset.输出中的Z
是零时区偏移的时区指示符。 It stands for Zulu and specifies the Etc/UTC
timezone (which has the timezone offset of +00:00
hours).它代表祖鲁语并指定Etc/UTC
时区(时区偏移为+00:00
小时)。 You can specify a different timezone offset (eg ZoneOffset.of("+05:30")
) as per your requirement.您可以根据您的要求指定不同的时区偏移量(例如ZoneOffset.of("+05:30")
)。
ZoneId
available如果您有可用的ZoneId
If you have ZoneId
available, you should parse the given date-time string into a LocalDateTime
and then apply the ZoneId
to it to get a ZonedDateTime
from which you can always obtain an OffsetDateTime
.如果您有可用的ZoneId
,则应将给定的日期时间字符串解析为LocalDateTime
,然后将ZoneId
应用于它以获取ZonedDateTime
,您始终可以从中获取OffsetDateTime
。 The best thing about a ZonedDateTime
is that it has been designed to adjust the timezone offset automatically whereas an OffsetDateTime
is used to represent a fixed timezone offset. ZonedDateTime
最好的一点是它旨在自动调整时区偏移,而OffsetDateTime
用于表示固定的时区偏移。
Demo:演示:
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);
}
}
Output:输出:
2021-08-17T13:26:49Z
You can specify a different ZoneId
(eg ZoneId.of("Asia/Kolkata")
) as per your requirement.您可以根据您的要求指定不同的ZoneId
(例如ZoneId.of("Asia/Kolkata")
)。
Learn more about the modern Date-Time API * from Trail: Date Time .从Trail: Date Time 中了解有关现代日期时间 API * 的更多信息。
* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring . * 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 通过 desugaring 可用的 Java 8+ API 。 Note that Android 8.0 Oreo already provides support for java.time
.请注意,Android 8.0 Oreo 已提供对java.time
支持。
Better use a ZonedDateTime
- the difference being the Day Saving Time, and countries on with the same zone offset.更好地使用ZonedDateTime
- 不同之处在于日保存时间和具有相同区域偏移量的国家/地区。 Maybe using the default ZoneId
.也许使用默认的ZoneId
。
Well, the string you passed in does not contain zone information, while an OffsetDateTime
requires zone information.好吧,您传入的字符串不包含区域信息,而OffsetDateTime
需要区域信息。
So you'll have to set a value for it.所以你必须为它设置一个值。
You could use the DateTimeFormatterBuilder
class, which then can be instructed to use some default value if a field is missing from the parsed information:您可以使用DateTimeFormatterBuilder
类,如果解析信息中缺少某个字段,则可以指示该类使用一些默认值:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.appendPattern("yyyyMMddHHmmss")
.toFormatter(Locale.ROOT);
You could also directly set an implied zone to the DateTimeFormatter
:您还可以直接为DateTimeFormatter
设置一个隐含区域:
DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.