Java:解析ISO_DATE / ISO_OFFSET_DATE [英] Java: parse ISO_DATE / ISO_OFFSET_DATE

查看:319
本文介绍了Java:解析ISO_DATE / ISO_OFFSET_DATE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于REST Web服务,我需要返回带有时区的日期(无时间)

For a REST web service, I need to return dates (no time) with a time zone.

显然没有这样的日期在Java中是 ZonedDate 的东西(仅 LocalDate ZonedDateTime ),因此我使用 ZonedDateTime 作为后备。

Apparently there is no such thing as a ZonedDate in Java (only LocalDate and ZonedDateTime), so I'm using ZonedDateTime as a fallback.

将这些日期转换为JSON时,我使用 DateTimeFormatter.ISO_OFFSET_DATE 格式化日期,确实很好:

When converting those dates to JSON, I use DateTimeFormatter.ISO_OFFSET_DATE to format the date, which works really well:

DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE;
ZonedDateTime dateTime = ZonedDateTime.now();
String formatted = dateTime.format(formatter);




2018-04-19 + 02:00

2018-04-19+02:00

但是,尝试用...解析这样的日期。

However, attempting to parse back such a date with...

ZonedDateTime parsed = ZonedDateTime.parse(formatted, formatter);

...导致异常:

java.time.format.DateTimeParseException:无法解析文本'2018-04-19 + 02:00':无法从TemporalAccessor获取ZonedDateTime:{OffsetSeconds = 7200},ISO解析为类型为java.time.format.Parsed的2018-04-19

java.time.format.DateTimeParseException: Text '2018-04-19+02:00' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {OffsetSeconds=7200},ISO resolved to 2018-04-19 of type java.time.format.Parsed

我也尝试过 ISO_DATE 并遇到了相同的问题。

I also tried ISO_DATE and ran into the same problem.

我如何解析这样的分区日期?

还是我应该将其他任何类型(在Java Time API中使用)用于分区日期?

How can I parse such a zoned date back?
Or is there any other type (within the Java Time API) I'm supposed to use for zoned dates?

推荐答案

问题是 ZonedDateTime 需要构建所有日期和时间字段(年,月,日,时,分,秒,纳秒),但是格式化程序 ISO_OFFSET_DATE 会生成不带时间部分的字符串。

The problem is that ZonedDateTime needs all the date and time fields to be built (year, month, day, hour, minute, second, nanosecond), but the formatter ISO_OFFSET_DATE produces a string without the time part.

解析时,与时间无关字段(小时,分钟,秒),您会得到一个 DateTimeParseException

When parsing it back, there are no time-related fields (hours, minutes, seconds) and you get a DateTimeParseException.

一种解析方法是使用 DateTimeFormatterBuilder 并定义时间字段的默认值。当您在回答中使用 atStartOfDay 时,我假设您想午夜,所以您可以执行以下操作:

One alternative to parse it is to use a DateTimeFormatterBuilder and define default values for the time fields. As you used atStartOfDay in your answer, I'm assuming you want midnight, so you can do the following:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // date and offset
    .append(DateTimeFormatter.ISO_OFFSET_DATE)
    // default values for hour and minute
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    .toFormatter();
ZonedDateTime parsed = ZonedDateTime.parse("2018-04-19+02:00", fmt); // 2018-04-19T00:00+02:00






您的解决方案也可以很好地工作,但是唯一的问题是您要解析输入两次 >(每次调用 formatter.parse 都会再次解析输入)。更好的选择是使用 parse 方法而不进行时间查询(仅分析一次),然后使用已分析的对象来获取所需的信息。


Your solution also works fine, but the only problem is that you're parsing the input twice (each call to formatter.parse will parse the input again). A better alternative is to use the parse method without a temporal query (parse only once), and then use the parsed object to get the information you need.

DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE;
// parse input
TemporalAccessor parsed = formatter.parse("2018-04-19+02:00");

// get data from the parsed object
LocalDate date = LocalDate.from(parsed);
ZoneId zone = ZoneId.from(parsed);
ZonedDateTime restored = date.atStartOfDay(zone); // 2018-04-19T00:00+02:00

使用此解决方案,将解析输入只有一次。

With this solution, the input is parsed only once.

这篇关于Java:解析ISO_DATE / ISO_OFFSET_DATE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆