将日期字符串转换为 ZonedDateTime
Converting Date String to ZonedDateTime
我收到一个 查询参数 日期,如 yyyy-MM-DD (2022-03-08)
。
我想将其转换为 java.util.Calendar
/ java.util.GregorianCalendar
格式。
所以我的想法是:
字符串 -> ZonedDateTime -> 日历。
我做了什么:
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()
的参数。
我还能尝试什么?
除了它的静态 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
,具体取决于您是否需要跟踪时区。我想,无论哪种方式,这都可以让您到达您想去的地方,因为一旦您拥有 ZonedDateTime
.
,听起来您就知道自己想做什么了
更新:我查看了如何将 ZoneDateTime 转换为日历:
Calendar calendar = GregorianCalendar.from(zoned);
以防万一你还没有走那么远并且真的想走那条路。
I want to conver this to java.util.Calendar / java.util.GregorianCalendar formmat.
这似乎很愚蠢; Calendar/GregorianCalendar 已过时,API 可怕。既然工具箱里有一把闪亮的新螺丝刀,为什么还要使用破损的螺丝刀呢?不要这样做。
So my idea is converto: String -> ZonedDateTime -> Calendar.
这似乎很愚蠢。该字符串不包含 ZonedDateTime
。它甚至不包含 LocalDateTime
。分明就是一个LocalDate
。因此,将其转换为本地日期,然后从那里开始。
java.time
包的强大之处在于,每个不同的概念及时在 j.t 包中都有一个正确命名的匹配类型。例如,java.util.Date
是一个谎言:它是一个时间戳,与日期没有任何关系;为 'what year is it' 询问 Date 对象已损坏(尝试一下,您会收到警告)。
日历同样是一个彻头彻尾的谎言。它根本不代表日历;它也代表一个时间戳。
另一方面,LocalDate
是完全正确的:它代表日期(不是时间),并且不包括时区或其他本地化信息:只有 'locally' 才有意义。
每一站都应该有意义,就其本身而言:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse("2022-10-01", formatter);
到目前为止,还不错。我就停在那里 - 为什么说谎?为什么 return 日历既是 API 明智的谎言(class 不代表日历),即使有人确切地知道日历是什么,它仍然是 一个谎言:日历意味着它有准确的时间 和 一个时区。你没有有时间,也没有时区。为什么 return 暗示一些不存在的东西?
但是,如果必须,请显式添加时区和时间,然后继续:
ZonedDateTime zdt = someLocalDate.atStartOfDay().atZone(ZoneId.of("Europe/Amsterdam"));
GregorianCalendar gc = GregorianCalendar.from(zdt);
这段代码清晰易读:crystal清楚地表明代码选择了一个时间,选择了一个区域。
但是,再一次,现在你得到了一个你不应该为任何事情使用的可怕的、可怕的对象。
我收到一个 查询参数 日期,如 yyyy-MM-DD (2022-03-08)
。
我想将其转换为 java.util.Calendar
/ java.util.GregorianCalendar
格式。
所以我的想法是: 字符串 -> ZonedDateTime -> 日历。
我做了什么:
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()
的参数。
我还能尝试什么?
除了它的静态 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
,具体取决于您是否需要跟踪时区。我想,无论哪种方式,这都可以让您到达您想去的地方,因为一旦您拥有 ZonedDateTime
.
更新:我查看了如何将 ZoneDateTime 转换为日历:
Calendar calendar = GregorianCalendar.from(zoned);
以防万一你还没有走那么远并且真的想走那条路。
I want to conver this to java.util.Calendar / java.util.GregorianCalendar formmat.
这似乎很愚蠢; Calendar/GregorianCalendar 已过时,API 可怕。既然工具箱里有一把闪亮的新螺丝刀,为什么还要使用破损的螺丝刀呢?不要这样做。
So my idea is converto: String -> ZonedDateTime -> Calendar.
这似乎很愚蠢。该字符串不包含 ZonedDateTime
。它甚至不包含 LocalDateTime
。分明就是一个LocalDate
。因此,将其转换为本地日期,然后从那里开始。
java.time
包的强大之处在于,每个不同的概念及时在 j.t 包中都有一个正确命名的匹配类型。例如,java.util.Date
是一个谎言:它是一个时间戳,与日期没有任何关系;为 'what year is it' 询问 Date 对象已损坏(尝试一下,您会收到警告)。
日历同样是一个彻头彻尾的谎言。它根本不代表日历;它也代表一个时间戳。
另一方面,LocalDate
是完全正确的:它代表日期(不是时间),并且不包括时区或其他本地化信息:只有 'locally' 才有意义。
每一站都应该有意义,就其本身而言:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse("2022-10-01", formatter);
到目前为止,还不错。我就停在那里 - 为什么说谎?为什么 return 日历既是 API 明智的谎言(class 不代表日历),即使有人确切地知道日历是什么,它仍然是 一个谎言:日历意味着它有准确的时间 和 一个时区。你没有有时间,也没有时区。为什么 return 暗示一些不存在的东西?
但是,如果必须,请显式添加时区和时间,然后继续:
ZonedDateTime zdt = someLocalDate.atStartOfDay().atZone(ZoneId.of("Europe/Amsterdam"));
GregorianCalendar gc = GregorianCalendar.from(zdt);
这段代码清晰易读:crystal清楚地表明代码选择了一个时间,选择了一个区域。
但是,再一次,现在你得到了一个你不应该为任何事情使用的可怕的、可怕的对象。