检查给定格式字符串可用于解析的时态类型



我得到一些用户输入的日期时间格式字符串,并且需要检查我可以用该格式解析数据的java.time时间(在合理的范围内,我现在倾向于只支持更简单的情况)。

类似于这个表格的内容:

tbody> <<tr>
输入格式 期望答案
yyyy-MMjava.time.YearMonth
MM/dd/yyyyjava.time.LocalDate
yyyy:DDjava.time.LocalDate(因为day-of-year数据)
HH:mm:ssjava.time.LocalTime
dd MM yyyy hh:mm:ssVjava.time.ZonedDateTime

DateTimeFormatter::parseBest()

我相信你的话:

请记住,日期格式和日期都是由用户,…

所以我假设我可以同时使用格式模式和输入的日期字符串,看看我能做什么。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()的参数列表中,必须将持有最多信息的类放在首位。或者你更喜欢哪门课,但我假设你想要尽可能多的信息。parseBest()使用第一个查询。因此,如果您打算支持后三者中的任何一个,请将ZonedDateTime放在第一位,Year,MonthDayOfWeek放在最后。

记得决定你想要的语言环境。

只有格式模式字符串

如果你想在没有要解析的字符串的情况下完成这个任务,它并不会变得更复杂。从使用从格式模式字符串构造的格式化程序格式化一些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)

最新更新