繁体   English   中英

将日期字符串转换为 ZonedDateTime

[英]Converting Date String to ZonedDateTime

我收到查询参数日期,如yyyy-MM-DD (2022-03-08)
我想将其转换为java.util.Calendar / java.util.GregorianCalendar格式。

所以我的想法是 converto: String -> ZonedDateTime -> Calendar。

我做了什么:

ZonedDateTime parsedDate = ZonedDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//date = 2022-03-08

即使格式正确,我也会得到:

Text '2022-03-08' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2022-03-08 of type java.time.format.Parsed

我发现发生此错误是因为我的字符串没有时区。

一个建议是使用LocalDate

 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
 LocalDate date = LocalDate.parse(fecha, formatter);

但我不能将localDate用作ZonedDateTime.parse()的参数。

我还能尝试什么?

我想将其转换为 java.util.Calendar / java.util.GregorianCalendar 格式。

这看起来很傻; Calendar/GregorianCalendar 已过时,API 太可怕了。 工具箱中有一把 shiny 新螺丝刀,为什么还要使用坏掉的螺丝刀? 不要这样做。

所以我的想法是 converto: String -> ZonedDateTime -> Calendar。

这看起来很傻。 该字符串不包含ZonedDateTime 它甚至不包含LocalDateTime 它显然是LocalDate 因此,将其转换为本地日期,然后从那里得到 go。

java.time package 的强大之处在于,每个不同的时间概念在 jt package 中都有一个正确命名的匹配类型。 例如, java.util.Date是一个谎言:它是一个时间戳,与日期无关; 向日期 object 询问“现在是哪一年”,已损坏(尝试一下,您会收到警告)。

同样,日历是一个彻头彻尾的谎言。 它根本不代表日历; 它也代表一个时间戳。

另一方面, LocalDate是完美的事实:它代表日期(不是时间),并且不包括时区或其他本地化信息:它仅在“本地”时才有意义。

每一站都应该有意义,就其本身而言:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse("2022-10-01", formatter);

到目前为止,一切都很好。 我就停在那里 - 为什么说谎? 为什么要返回一个既是 API 又是谎言的日历(class 不代表日历),即使有人确切地知道日历是什么,它仍然是一个谎言:日历意味着它有准确的时间时区。 没有时间,也没有时区。 为什么要退回暗示不存在的东西?

但是,如果必须,则明确添加时区和时间,然后为其添加 go:

ZonedDateTime zdt = someLocalDate.atStartOfDay().atZone(ZoneId.of("Europe/Amsterdam"));
GregorianCalendar gc = GregorianCalendar.from(zdt);

这段代码清晰易读:它清楚地表明代码选择了一个时间,并选择了一个区域。

但是,现在你又得到了一个可怕的、可怕的 object,你不应该为任何事情使用它。

除了 static parse()方法之外,还有其他获取ZonedDateTime的方法。 以下是将LocalDateTime转换为ZonedDateTime的方法:

ZonedDateTime zoned = dateTime.atZone(ZoneId.of( "America/New_York"));

或者如果你有一个LocalDate

ZonedDateTime zoned = 
          date.atStartOfDay( ZoneId.of( "America/New_York" ));

我不会使用java.util.CalendarDate 他们是垃圾。 我会坚持使用LocalDate或使用ZonedDateTime ,具体取决于您是否需要跟踪时区。 无论哪种方式,这都应该让你到达你想要的位置 go ,我猜,因为听起来你知道一旦你有了ZonedDateTime ,你想做什么。

更新:我查找了如何将 ZoneDateTime 转换为日历:

Calendar calendar = GregorianCalendar.from(zoned);

以防万一您还没有走那么远并且真的想那样做 go。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM