Deb*_*tra 5 java datetime date datetime-format java-date
我的要求是根据一组指定的有效格式来验证日期字符串的格式正确。
有效格式:
MM/dd/yy
MM/dd/yyyy
Run Code Online (Sandbox Code Playgroud)
我创建了一个简单的测试方法,该方法使用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");
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行此,这里是输出
10/30/2017 has an invalid date format
Run Code Online (Sandbox Code Playgroud)
如您在代码中看到的,有效的日期格式是MM / dd / yy和MM / dd / yyyy。我的期望是日期10/30/2017应该有效,因为它与MM / dd / yyyy相匹配。但是,2017年10月30日被报告为无效。
怎么了?为什么这不起作用?
我也试过
.appendOptional(DateTimeFormatter.ofPattern("MM/dd/yy[yy]"))
Run Code Online (Sandbox Code Playgroud)
代替
.appendOptional(DateTimeFormatter.ofPattern("MM/dd/yy"))
.appendOptional(DateTimeFormatter.ofPattern("MM/dd/yyyy"))
Run Code Online (Sandbox Code Playgroud)
但仍然存在相同的问题。
如果使用以下代码,此代码将按预期运行:
String dateString = "10/30/17";
Run Code Online (Sandbox Code Playgroud)
代替
String dateString = "10/30/2017";
Run Code Online (Sandbox Code Playgroud)
我有两个问题
这是怎么了?为什么对“ 10/30/2017”不起作用?
使用Java 8,如何正确创建灵活的Date格式化程序(支持多种可选格式的格式化程序)?我知道使用[]在模式字符串本身中创建可选部分。我正在寻找与尝试的内容类似的东西(避免在模式字符串中使用[],并为每个单独的格式字符串使用单独的可选子句)
格式化程序没有按您期望的方式工作,可选部分意味着
为了使它更清楚一点,请尝试运行下面的示例代码以更好地理解它:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
==
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
Run Code Online (Sandbox Code Playgroud)
==
这只是一个简单的解决方案,如果您关心性能,则通过捕获解析异常进行验证应该是最后的手段
您还可以用包含简单 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;
});
Run Code Online (Sandbox Code Playgroud)