[英]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.Calendar
或Date
。 他们是垃圾。 我会坚持使用LocalDate
或使用ZonedDateTime
,具体取决于您是否需要跟踪时区。 无论哪种方式,这都应该让你到达你想要的位置 go ,我猜,因为听起来你知道一旦你有了ZonedDateTime
,你想做什么。
更新:我查找了如何将 ZoneDateTime 转换为日历:
Calendar calendar = GregorianCalendar.from(zoned);
以防万一您还没有走那么远并且真的想那样做 go。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.