gpt4 book ai didi

java - 检查给定格式字符串可用于解析的 Temporal 类型

转载 作者:行者123 更新时间:2023-12-04 13:05:26 31 4
gpt4 key购买 nike

我得到了一些用户输入的日期时间格式字符串,并且需要检查我可以解析该格式数据的 java.time 时间(在合理范围内,我打算只支持更简单的目前的案例)。

与此表类似的内容:

<表类="s-表"><头>输入格式预期答案<正文> 年月日 java.time.YearMonth 月/日/年 java.time.LocalDate yyyy:DD java.time.LocalDate(因为日期数据) HH:mm:ss java.time.LocalTime dd 月 yyyy hh:mm:ssV java.time.ZonedDateTime

请记住,日期格式和日期都是由用户输入的,因此这些输入格式只是示例,它们显然可以包含文字(但不是可选部分,这是一种解脱)。

到目前为止,我只能想出这种 if 的 Tornado 作为解决方案:

private static final ZonedDateTime ZDT = ZonedDateTime.of(1990, 10, 26, 14, 40, 59, 123456, ZoneId.of("Europe/Oslo"));
...
String formatted = externalFormatter.format(ZDT);
Class<?> type;
TemporalAccessor parsed = externalFormatter.parse(formatted);
if (parsed.isSupported(YEAR)) {
if (parsed.isSupported(MONTH_OF_YEAR)) {
if (parsed.query(TemporalQueries.localDate()) != null) {
if (parsed.query(TemporalQueries.localTime()) != null) {
if (parsed.query(TemporalQueries.zone()) != null) {
type = ZonedDateTime.class;
}
else if (parsed.query(TemporalQueries.offset()) != null) {
type = OffsetDateTime.class;
}
else {
type = LocalDateTime.class;
}
}
else {
type = LocalDate.class;
}
}
else {
type = YearMonth.class;
}
}
else {
type = Year.class;
}
}
else if (parsed.query(TemporalQueries.localTime()) != null) {
if (parsed.query(TemporalQueries.offset()) != null) {
type = OffsetTime.class;
}
else {
type = LocalTime.class;
}
}

当然,一定有更好的方法,至少在一定程度上是这样?我不会限制自己只使用 java.time,我也有可用的 Joda-Time 库(尽管它在技术上处于遗留状态),而且我不会拒绝使用更简单的代码SimpleDateFormat 如果有这样的选项。

最佳答案

DateTimeFormatter::parseBest()

我相信你的话:

Keeping in mind, that both the date format and the date are entered bythe user, …

所以我假设我可以同时使用格式模式和输入的日期字符串来查看我能用它做什么。 DateTimeFormatter::parseBest() 是我们需要的方法。

public static TemporalAccessor parse(String formatPattern, String toBeParsed) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, Locale.ROOT);
return formatter.parseBest(toBeParsed, ZonedDateTime::from,
LocalDate::from, LocalTime::from, YearMonth::from);
}

为了演示上述方法的强大功能,我使用了以下辅助方法:

public static void demo(String formatPattern, String toBeParsed) {
TemporalAccessor result = parse(formatPattern, toBeParsed);
System.out.format("%-21s %s%n", formatPattern, result.getClass().getName());
}

让我们用你的例子来调用它:

    demo("yyyy-MM", "2017-11");
demo("MM/dd/yyyy", "10/21/2023");
demo("yyyy:DD", "2021:303");
demo("HH:mm:ss", "23:34:45");
demo("dd MM yyyy HH:mm:ssVV", "05 09 2023 14:01:55Europe/Oslo");

我已经更正了最后一个格式模式字符串中的几个错误。输出是:

yyyy-MM               java.time.YearMonth
MM/dd/yyyy java.time.LocalDate
yyyy:DD java.time.LocalDate
HH:mm:ss java.time.LocalTime
dd MM yyyy HH:mm:ssVV java.time.ZonedDateTime

TemporalQueryparseBest() 的参数列表中,必须将包含最多信息的类放在最前面。或者你更喜欢哪些类(class),但我假设你想要尽可能多的信息。 parseBest() 使用有效的第一个 查询。因此,如果您打算支持最后三个中的任何一个,请将 ZonedDateTime 放在第一位,然后将 YearMonthDayOfWeek 放在最后。

请记住决定您想要的语言环境。

只有格式模式字符串

如果您打算在没有要解析的字符串的情况下执行此操作,那么它不会更复杂。首先使用您从格式模式字符串构建的格式化程序格式化一些 ZonedDateTime。然后使用 parseBest() 解析返回的字符串。您必须使用 ZonedDateTime,因为它是唯一一个包含格式模式字符串中可以想象的每个字段的类,因此对于其他一些类,格式设置可能会中断。另一方面,格式化字符串中的信息受模式限制,因此在大多数情况下,您将无法解析 ZonedDateTime。这正是我们想要的:parseBest() 将告诉我们可以解析到哪个类。

public static Class<? extends TemporalAccessor> getParseableType(String formatPattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, Locale.ROOT);
String example = ZonedDateTime.now(ZoneId.systemDefault()).format(formatter);
TemporalAccessor parseableTemporalAccessor = formatter.parseBest(example, ZonedDateTime::from,
LocalDate::from, LocalTime::from, YearMonth::from);
return parseableTemporalAccessor.getClass();
}

文档链接

parseBest​(CharSequence text, TemporalQuery<?>... queries)

关于java - 检查给定格式字符串可用于解析的 Temporal 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69746234/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com