Determine if a String is a valid date before parsi

2019-01-14 16:39发布

I have this situation where I am reading about 130K records containing dates stored as String fields. Some records contain blanks (nulls), some contain strings like this: 'dd-MMM-yy' and some contain this 'dd/MM/yyyy'.

I have written a method like this:

public Date parsedate(String date){

   if(date !== null){
      try{
        1. create a SimpleDateFormat object using 'dd-MMM-yy' as the pattern
        2. parse the date
        3. return the parsed date
      }catch(ParseException e){
          try{
              1. create a SimpleDateFormat object using 'dd/MM/yyy' as the pattern
              2. parse the date
              3. return parsed date
           }catch(ParseException e){
              return null
           }
      }
   }else{
      return null
   }

} 

So you may have already spotted the problem. I am using the try .. catch as part of my logic. It would be better is I can determine before hand that the String actually contains a parseable date in some format then attempt to parse it.

So, is there some API or library that can help with this? I do not mind writing several different Parse classes to handle the different formats and then creating a factory to select the correct6 one, but, how do I determine which one?

Thanks.

11条回答
趁早两清
2楼-- · 2019-01-14 17:18

Don't be too hard on yourself about using try-catch in logic: this is one of those situations where Java forces you to so there's not a lot you can do about it.

But in this case you could instead use DateFormat.parse(String, ParsePosition).

查看更多
成全新的幸福
3楼-- · 2019-01-14 17:20

you could use split to determine which format to use

String[] parts = date.split("-");
df = (parts.length==3 ? format1 : format2);

That assumes they are all in one or the other format, you could improve the checking if need be

查看更多
相关推荐>>
4楼-- · 2019-01-14 17:20

A simple utility class I have written for my project. Hope this helps someone.

Usage examples:

DateUtils.multiParse("1-12-12");
DateUtils.multiParse("2-24-2012");
DateUtils.multiParse("3/5/2012");
DateUtils.multiParse("2/16/12");




public class DateUtils {

    private static List<SimpleDateFormat> dateFormats = new ArrayList<SimpleDateFormat>();



    private Utils() {
        dateFormats.add(new SimpleDateFormat("MM/dd/yy")); // must precede yyyy
        dateFormats.add(new SimpleDateFormat("MM/dd/yyyy"));
        dateFormats.add(new SimpleDateFormat("MM-dd-yy"));
        dateFormats.add(new SimpleDateFormat("MM-dd-yyyy"));            

    }
        private static Date tryToParse(String input, SimpleDateFormat format) {
        Date date  = null;
        try {
            date = format.parse(input);
        } catch (ParseException e) {

        }

        return date;
    }

        public static Date multiParse(String input)  {
        Date date = null;
        for (SimpleDateFormat format : dateFormats) {
            date = tryToParse(input, format);
            if (date != null) break;
        }
        return date;
    }
}
查看更多
走好不送
5楼-- · 2019-01-14 17:21

You can take advantage of regular expressions to determine which format the string is in, and whether it matches any valid format. Something like this (not tested):

(Oops, I wrote this in C# before checking to see what language you were using.)

Regex test = new Regex(@"^(?:(?<formatA>\d{2}-[a-zA-Z]{3}-\d{2})|(?<formatB>\d{2}/\d{2}/\d{3}))$", RegexOption.Compiled);
Match match = test.Match(yourString);
if (match.Success)
{
    if (!string.IsNullOrEmpty(match.Groups["formatA"]))
    {
        // Use format A.
    }
    else if (!string.IsNullOrEmpty(match.Groups["formatB"]))
    {
        // Use format B.
    }
    ...
}
查看更多
在下西门庆
6楼-- · 2019-01-14 17:26

Looks like three options if you only have two, known formats:

  • check for the presence of - or / first and start with that parsing for that format.
  • check the length since "dd-MMM-yy" and "dd/MM/yyyy" are different
  • use precompiled regular expressions

The latter seems unnecessary.

查看更多
ゆ 、 Hurt°
7楼-- · 2019-01-14 17:27

An alternative to creating a SimpleDateFormat (or two) per iteration would be to lazily populate a ThreadLocal container for these formats. This will solve both Thread safety concerns and concerns around object creation performance.

查看更多
登录 后发表回答