How to parse ambiguous String into Date?

2020-07-18 10:22发布

I'm trying to figure out a "simple" way of parsing a String into a Date Object.

The String can be either yyyyMMdd, yyyyMMddHHmm or yyyyMMddHHmmSS.

Currently, I'm looking at the length of the String, and creating a DateParser depending on the length. Is there a more elegant way of doing this?

5条回答
我欲成王,谁敢阻挡
2楼-- · 2020-07-18 10:33

Or you can pad your string with zeros:

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmSS") {
  @Override
  public Date parse(String s) throws ParseException {
    return super.parse((s + "000000").substring(0, 14));
  }
};

System.out.println(sdf.format(sdf.parse("20110711182405")));
System.out.println(sdf.format(sdf.parse("201107111824")));
System.out.println(sdf.format(sdf.parse("20110711")));
查看更多
疯言疯语
3楼-- · 2020-07-18 10:34

You can use a DateFormatter to parse the Date from the string.

import java.util.*;
import java.text.*;

public class StringToDate
{
 public static void main(String[] args) 
 {
 try 
 {  
   String str_date="11-June-07";
   DateFormat formatter ; 
   Date date ; 
   formatter = new SimpleDateFormat("yyyy-MM-dd");
   date = (Date)formatter.parse(str_date);  

  } 
  catch (ParseException e)
  {
    System.out.println("Exception :"+e);  
  }  
 }
} 

You can change the pattern however you like to reflect your needs.

查看更多
别忘想泡老子
4楼-- · 2020-07-18 10:41

I would use a SimpleDateFormat class, and populate the format pattern based on the length of the string. That'll work fine unless you one day have strings of the same length.

Using the examples from your question:

Formatting 11th July 2011:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date parsedDate = dateFormat.parse("20110711");

Formatting 11th July 2011 1340hrs:

dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
parsedDate = dateFormat.parse("201107111340");

Formatting 11th July 2011 1340hrs 10 seconds:
(NB. small s for seconds, capital S is for Milliseconds!)

dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
parsedDate = dateFormat.parse("20110711134010");

See the hyperlink for the full list of format pattern letters.

查看更多
我命由我不由天
5楼-- · 2020-07-18 10:41

You could still used "specialized" parsers (as you suggested) and chain them: For instance, you can still have a DateHourMinSecParser (for yyyyMMddHHmmSS), a DateHourMinParser (for yyyyMMddHHmm) and a DateParser (for yyyyMMdd) all of them implementing the same interface:

public interface GenericDateParser {
 Date parseDate(String input) throws IllegalArgumentException;
}

e.g.

public class DateHourMinSecParser implements GenericDateParser {
...
     public Date parseDate(String input) throws IllegalArgumentException {
     ...
     }
}

but each one of these classes would actually take a parameter another GenericDateParser -- the idea being that each parser would try first to parse the date itself, if the parsing (or some internal checks -- e.g. string length) fails it would then pass it to the next parser in chain until either there are no more parsers in the chain (in which case it would throw an exception, or one of the members in the chain would return a value):

public class DateHourMinSecParser implements GenericDateParser {
     private GenericDateParser chained;

     public DateHourMinSecParser(GenericDateParser chained) {
       this.chained = chained;
     }

     public Date parseDate(String input) throws IllegalArgumentException {
      if( !internalChecks() ) { //chain it up
       if( chained == null ) throw new IllegalArgumentException( "Don't know how to parse " + input);
      }
      //internal checks passed so try to parse it and return a Date or throw exception
      ...
     }
}

and you would initialize them:

GenericDateParser p = new DateHourMinSecParser( new DateHourMinParser(new DateParser(null)) );

and then just use the top level one:

Date d = p.parse( '20110126' );
查看更多
女痞
6楼-- · 2020-07-18 10:44

I would do as you are, looking at the length of the string, and creating an appropriate SimpleDateFormat instance.

SimpleDateFormat getFormatFor( String dateString ){
    if ( dateString.length() == 8  ) return new SimpleDateFormat("yyyyMMdd");
    if ( dateString.length() == 14 ) return new SimpleDateFormat("yyyyMMddHHmmss");
    // you got a bad input...
}

NB these are not thread-safe, so you should create a new one each time.

查看更多
登录 后发表回答