Java 8 DateTimeFormatterBuilder()。appendOptional不工作
我的要求是基于指定的一组有效格式来验证日期字符串格式是否正确。Java 8 DateTimeFormatterBuilder()。appendOptional不工作
有效格式:
MM/dd/yy MM/dd/yyyy
我创建使用Java 8 DateTimeFormatterBuilder创建支持多个可选格式柔性格式化一个简单的测试方法。下面是代码:
public static void test() { DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendOptional(DateTimeFormatter.ofPattern("MM/dd/yy"))
.appendOptional(DateTimeFormatter.ofPattern("MM/dd/yyyy"))
.toFormatter();
String dateString = "10/30/2017";
try {
LocalDate.parse(dateString, formatter);
System.out.println(dateString + " has a valid date format");
} catch (Exception e) {
System.out.println(dateString + " has an invalid date format");
}
}
当我运行此,这里是输出
10/30/2017 has an invalid date format
正如你在代码中看到,有效的日期格式是MM/DD/YY和MM/DD/YYYY。 我的预计是,日期10/30/2017应该是有效的,因为它匹配MM/dd/yyyy。但是,10/30/2017被报告为无效。
什么问题?为什么这不起作用?
我也试过
代替
.appendOptional(DateTimeFormatter.ofPattern("MM/dd/yy")) .appendOptional(DateTimeFormatter.ofPattern("MM/dd/yyyy"))
,但仍然有同样的问题。
此代码按预期运行,如果我使用:
String dateString = "10/30/17";
代替
String dateString = "10/30/2017";
我有2个问题
这是怎么回事错在这里?为什么它不适用于“10/30/2017”?如何正确创建一个灵活的日期格式化程序(一个支持多种可选格式的格式化程序)?我知道使用[]在模式字符串本身中创建可选部分。我在找东西更类似于我想(避免[模式字符串中]和使用单独的可选子句对每个单独的格式字符串)
回答:
格式化不工作,你所期望的方式,可选的部分是指
- 如果没有什么额外的连接到第一图案(例如,“MM/DD/YY”),这是没有问题,
- 如果有额外的东西,它需要匹配第二模式(例如,克, “MM/DD/YYYY”)
为了使它更清楚一点,尝试运行,下面的示例代码,以便更好地理解它:
DateTimeFormatter formatter = new DateTimeFormatterBuilder() .appendOptional(DateTimeFormatter.ofPattern("MM/dd/yy"))
.appendOptional(DateTimeFormatter.ofPattern("MM/dd/yyyy"))
.toFormatter();
String[] dateStrings = {
"10/30/17", // valid
"10/30/2017", // invalid
"10/30/1710/30/2017", // valid
"10/30/201710/30/17" // invalid
};
for (String dateString : dateStrings) {
try {
LocalDate.parse(dateString, formatter);
System.out.println(dateString + " has a valid date format");
} catch (Exception e) {
System.err.println(dateString + " has an invalid date format");
}
}
==
10/30/17 has a valid date format 10/30/1710/30/2017 has a valid date format
10/30/2017 has an invalid date format
10/30/201710/30/17 has an invalid date format
==
这只是一个简单的解决方案,如果性能是您的顾虑,通过捕获解析异常的验证应该是las吨景区
- 你可能首先执行日期字符串解析
你还可以用含有简单的for循环的方法替换流之前检查由长度或正则表达式的串等
String[] patterns = { "MM/dd/yy", "MM/dd/yyyy" };
Map<String, DateTimeFormatter> formatters = Stream.of(patterns).collect(Collectors.toMap(
pattern -> pattern,
pattern -> new DateTimeFormatterBuilder().appendOptional(DateTimeFormatter.ofPattern(pattern)).toFormatter()
));
String dateString = "10/30/17";
boolean valid = formatters.entrySet().stream().anyMatch(entry -> {
// relying on catching parsing exception will have serious expense on performance
// a simple check will already improve a lot
if (dateString.length() == entry.getKey().length()) {
try {
LocalDate.parse(dateString, entry.getValue());
return true;
}
catch (DateTimeParseException e) {
// ignore or log it
}
}
return false;
});
回答:
建造者的appendValueReduced()
方法被设计来处理这种情况。
当解析一个字段的完整的价值,格式化会将其作为一个绝对值。
当解析为一个字段的部分值,格式器将解释它相对于所指定的位置。例如,如果要将两位数年份解释为1970年至2069年,则可以指定1970年为基数。下面是一个例子:
LocalDate century = LocalDate.ofEpochDay(0); /* Beginning Jan. 1, 1970 */ DateTimeFormatter f = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ofPattern("MM/dd/"))
.appendValueReduced(ChronoField.YEAR, 2, 4, century)
.toFormatter();
System.out.println(LocalDate.parse("10/30/2017", f)); /* 2017-10-30 */
System.out.println(LocalDate.parse("10/30/17", f)); /* 2017-10-30 */
System.out.println(LocalDate.parse("12/28/1969", f)); /* 1969-12-28 */
System.out.println(LocalDate.parse("12/28/69", f)); /* 2069-12-28 */
以上是 Java 8 DateTimeFormatterBuilder()。appendOptional不工作 的全部内容, 来源链接: utcz.com/qa/267176.html