How to check validity of Date String?
In my project I need to check if a date string evaluates to a proper Date object. I've decided to allow yyyy-MM-dd, and Date formats [(year, month, date) and (year, month, date, hrs, min)]. How can I check if they're valid ? My code returns null for "1980-01-01" and some strange dates (like 3837.05.01) whon giving a string separated by commas :
private Date parseDate(String date){
Date data = null;
// yyy-mm-dd
try {
开发者_如何学Python DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
df.setLenient(false);
df.parse(date);
return data;
}
catch (Exception e) {
try{
int[] datArr = parseStringForDate(date);
int len = datArr.length;
// year, month, day
if(len == 3){
return new Date(datArr[0], datArr[1], datArr[2]);
}
// year, montd, day, hours, mins
else if(len ==5){
return new Date(datArr[0], datArr[1], datArr[2], datArr[3], datArr[4]);
}
// year, month, day, hours, mins, secs
else if(len == 6){
return new Date(datArr[0], datArr[1], datArr[2], datArr[3], datArr[4], datArr[5]);
}
else {
return data;
}
}
catch (Exception f){
return data;
}
}
}
private int[] parseStringForDate(String s){
String[] sArr = s.split(",");
int[] dateArr = new int[sArr.length];
for(int i=0; i< dateArr.length; i++){
dateArr[i] = Integer.parseInt(sArr[i]);
}
return dateArr;
}
I remember that I had to subtract 1900 from year date, but I also see that month is different etc, and I'd like to avoid checking every element of my array of ints from date string. Is it possible to parse them automatically in Calendar or date object ?
You can construct SimpleDateFormat objects for your different String formats like this (returning null
if the parameter cannot be parsed as a valid date):
// Initializing possibleFormats somewhere only once
SimpleDateFormat[] possibleFormats = new SimpleDateFormat[] {
new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyy,MM,dd"),
new SimpleDateFormat("yyyy,MM,dd,HH,mm") };
for (SimpleDateFormat format: possibleFormats)
{
format.setLenient(false);
}
// initializing ends
public Date parseDate(String date) {
Date retVal = null;
int index = 0;
while (retVal == null && index < possibleFormats.length) {
try {
retVal = possibleFormats[index++].parse(date);
} catch (ParseException ex) { /* Do nothing */ }
}
return retVal;
}
For anyone popping by in 2017 or later, here is the Java 8 solution:
private static DateTimeFormatter[] possibleFormats = {
DateTimeFormatter.ofPattern("uuuu-MM-dd").withResolverStyle(ResolverStyle.STRICT),
DateTimeFormatter.ofPattern("uuuu,MM,dd").withResolverStyle(ResolverStyle.STRICT),
DateTimeFormatter.ofPattern("uuuu,MM,dd,HH,mm").withResolverStyle(ResolverStyle.STRICT),
DateTimeFormatter.ofPattern("uuuu,MM,dd,HH,mm,ss").withResolverStyle(ResolverStyle.STRICT)
};
public Optional<LocalDate> parseDate(String date) {
for (DateTimeFormatter format : possibleFormats) {
try {
LocalDate result = LocalDate.parse(date, format);
return Optional.of(result);
} catch (DateTimeParseException dtpe) {
// ignore, try next format
}
}
return Optional.empty();
}
With DateTimeFormatter
you can safely let the array of formatters be static even in a multithreaded environment: unlike SimpleDateFormat
, a DateTimeFormatter
is thread safe.
A LocalDate
is a date without a time, so if any hours and minutes were present in the string, they are lost. To get the hours, minutes and seconds out too you need a LocalDateTime
, and then you need some trickery to make the parsing work in the cases where there are no hours and minutes in the string. You may either try both LocalDate.parse()
and LocalDateTime.parse()
, or you may build a formatter that has a default for hours to use when not in the string. DateTimeFormatterBuilder
can do that.
You are doing this the wrong way. You should use SimpleDateFormat.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date test = sdf.parse(input);
} catch (ParseException pe) {
//Date is invalid, try next format
}
Just to show the final outcome, thanks to Csaba_H and Steve Kuo.
private Date parseDate(String date){
SimpleDateFormat[] possibleFormats = new SimpleDateFormat[] {
new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyy,MM,dd"),
new SimpleDateFormat("yyyy,MM,dd,HH,mm") };
Date retVal = null;
for (SimpleDateFormat f: possibleFormats) {
f.setLenient(false);
try {
retVal = f.parse(date);
} catch (ParseException e) {}
}
return retVal;
}
精彩评论