验证 Java 中的日期字符串时出现异常
Exception while validating a date string in Java
我发现了一个很好的函数,它可以验证日期的格式和正确性 String
。我想升级它以仅验证 >= 1900
年。
这就是我的发现:
public boolean isDateValid(String date) {
try {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
df.setLenient(false);
df.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}
这是我的升级版:
public boolean isDateValid(String date) {
try {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
df.setLenient(false);
df.parse(date);
Integer year = Integer.parseInt(date.substring(6, 10));
if (year>= 1900)
return true;
else
return false;
} catch (ParseException e) {
return false;
}
}
所以我没有返回 true,而是检查 year
变量是否大于或等于 1900。问题是当我 运行 这个函数与 "12-12-1xxx"
(编辑:或"12-12-1abc"
)。将年份 String
解析为 int
时抛出 NumberFormatException
。这绝对不应该发生,因为 ParseException
应该首先抛出,打破 try {}
块。
第一个列表的验证似乎无法正常工作,因为它接受每个以数字开头的 "yyyy"
部分。然而,对于 "12-12-xxxx"
(edit:或 "12-12-abcd"
),一切正常。
编辑:
在阅读时停止对我的问题投反对票并集中注意力。问题很明确:为什么 new SimpleDateFormat("dd-MM-yyyy").parse("12-12-1xxx") 不抛出 ParseException?
我已经检查了你的功能,并找到了以下详细信息。
如果你在 main 函数中传递 12-12-1xxx
那么你也会得到 true 它不会 return false 即使当我打印日期输出时由 df.parse(date)
转换为 Oct 10 00:00:00 GMT 2.
所以你不会在任何时候得到解析异常,
建议
您可以通过 Exception 更改 ParseException,也可以像下面那样对 NumberFormatException 使用 catch。
public boolean isDateValid(String date) {
try {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
df.setLenient(false);
df.parse(date);
Integer year = Integer.parseInt(date.substring(6, 10));
if (year>= 1900)
return true;
else
return false;
} catch (Exception e) { // Use Exception or if you want ParseException then use below commented code
return false;
}
/*catch (NumberFormatException nfe) { // Use this if you use ParseException
return false;
}*/
}
正如我从 javadoc 中了解到的那样,SimpleDateFormat 会将 1 作为一年中的有效部分并将对其进行解析。相反,您可以尝试使用正则表达式来验证日期。您可以在此处找到一些示例 Regex to validate date format dd/mm/yyyy
parse
方法的文档是:
Parses text from the beginning of the given string to produce a date.
The method may not use the entire text of the given string.
因为不需要使用整个字符串,所以“12-12-1xxx”实际上被解析为“12-12-1”,得到的是1年的日期。
您可以使用解析方法的结果来获取年份,而不是使用子字符串。 getYear
已折旧,returns 是从 1900 开始的偏移量,因此您可能希望先转换为 Calendar
或 LocalDate
。
public boolean isDateValid(String date) {
try {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
df.setLenient(false);
Date parsed = df.parse(date);
int year = parsed.getYear() + 1900;
if (year >= 1900)
return true;
else
return false;
} catch (ParseException e) {
return false;
}
}
如果有人对代码的外观感兴趣,请看这里:
public boolean isDateValid(String date, String format) {
if (date.length()!=format.length())
return false;
try {
DateFormat df = new SimpleDateFormat(format);
df.setLenient(false);
df.parse(date); // exception is not thrown if day and month is
// correct AND the first char of year is a digit
// so if we have correct day and correct month
// and we know the year has 4 chars we can try to parse it
Integer year = Integer.parseInt(date.substring(6, 10));
if (year>= 1900 && year<=2015) // here we know that the year is 4 digit integer
return true; // and we can limit it
else
return false;
} catch (ParseException e) {
return false;
} catch (NumberFormatException e) {
return false;
}
}
我发现了一个很好的函数,它可以验证日期的格式和正确性 String
。我想升级它以仅验证 >= 1900
年。
这就是我的发现:
public boolean isDateValid(String date) {
try {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
df.setLenient(false);
df.parse(date);
return true;
} catch (ParseException e) {
return false;
}
}
这是我的升级版:
public boolean isDateValid(String date) {
try {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
df.setLenient(false);
df.parse(date);
Integer year = Integer.parseInt(date.substring(6, 10));
if (year>= 1900)
return true;
else
return false;
} catch (ParseException e) {
return false;
}
}
所以我没有返回 true,而是检查 year
变量是否大于或等于 1900。问题是当我 运行 这个函数与 "12-12-1xxx"
(编辑:或"12-12-1abc"
)。将年份 String
解析为 int
时抛出 NumberFormatException
。这绝对不应该发生,因为 ParseException
应该首先抛出,打破 try {}
块。
第一个列表的验证似乎无法正常工作,因为它接受每个以数字开头的 "yyyy"
部分。然而,对于 "12-12-xxxx"
(edit:或 "12-12-abcd"
),一切正常。
编辑:
在阅读时停止对我的问题投反对票并集中注意力。问题很明确:为什么 new SimpleDateFormat("dd-MM-yyyy").parse("12-12-1xxx") 不抛出 ParseException?
我已经检查了你的功能,并找到了以下详细信息。
如果你在 main 函数中传递 12-12-1xxx
那么你也会得到 true 它不会 return false 即使当我打印日期输出时由 df.parse(date)
转换为 Oct 10 00:00:00 GMT 2.
所以你不会在任何时候得到解析异常,
建议
您可以通过 Exception 更改 ParseException,也可以像下面那样对 NumberFormatException 使用 catch。
public boolean isDateValid(String date) {
try {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
df.setLenient(false);
df.parse(date);
Integer year = Integer.parseInt(date.substring(6, 10));
if (year>= 1900)
return true;
else
return false;
} catch (Exception e) { // Use Exception or if you want ParseException then use below commented code
return false;
}
/*catch (NumberFormatException nfe) { // Use this if you use ParseException
return false;
}*/
}
正如我从 javadoc 中了解到的那样,SimpleDateFormat 会将 1 作为一年中的有效部分并将对其进行解析。相反,您可以尝试使用正则表达式来验证日期。您可以在此处找到一些示例 Regex to validate date format dd/mm/yyyy
parse
方法的文档是:
Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.
因为不需要使用整个字符串,所以“12-12-1xxx”实际上被解析为“12-12-1”,得到的是1年的日期。
您可以使用解析方法的结果来获取年份,而不是使用子字符串。 getYear
已折旧,returns 是从 1900 开始的偏移量,因此您可能希望先转换为 Calendar
或 LocalDate
。
public boolean isDateValid(String date) {
try {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
df.setLenient(false);
Date parsed = df.parse(date);
int year = parsed.getYear() + 1900;
if (year >= 1900)
return true;
else
return false;
} catch (ParseException e) {
return false;
}
}
如果有人对代码的外观感兴趣,请看这里:
public boolean isDateValid(String date, String format) {
if (date.length()!=format.length())
return false;
try {
DateFormat df = new SimpleDateFormat(format);
df.setLenient(false);
df.parse(date); // exception is not thrown if day and month is
// correct AND the first char of year is a digit
// so if we have correct day and correct month
// and we know the year has 4 chars we can try to parse it
Integer year = Integer.parseInt(date.substring(6, 10));
if (year>= 1900 && year<=2015) // here we know that the year is 4 digit integer
return true; // and we can limit it
else
return false;
} catch (ParseException e) {
return false;
} catch (NumberFormatException e) {
return false;
}
}