Date time parsing that accepts 05/05/1999 and 5/5/

2019-04-09 21:58发布

Is there a simple way to parse a date that may be in MM/DD/yyyy, or M/D/yyyy, or some combination? i.e. the zero is optional before a single digit day or month.

To do it manually, one could use:

String[] dateFields = dateString.split("/");
int month = Integer.parseInt(dateFields[0]);
int day = Integer.parseInt(dateFields[1]);
int year = Integer.parseInt(dateFields[2]);

And validate with:

dateString.matches("\\d\\d?/\\d\\d?/\\d\\d\\d\\d")

Is there a call to SimpleDateFormat or JodaTime that would handle this?

3条回答
仙女界的扛把子
2楼-- · 2019-04-09 22:38

java.time

Java 8 and later includes the java.time framework. This framework obsoletes the old java.util.Date/.Calendar classes discussed in the other answers here.

The java.time.format package and its java.time.format.DateTimeFormatter class use pattern codes similar to that seen in the accepted Answer by Ray Myers. While similar, they vary a bit. In particular they are strict about the number of repeated characters. If you say MM, then the month must have padded zero or else you get a DateTimeParseException. If the month number may or may not have a padding zero, simply use the single-character M.

In this example code, note how the month number of the input string has a padding zero while the day-of-month number does not. Both are handled by the single-character pattern.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "M/d/yyyy" );
LocalDate localDate = formatter.parse ( "01/2/2015" , LocalDate :: from );

Dump to console.

System.out.println ( "localDate: " + localDate );

localDate: 2015-01-02

查看更多
虎瘦雄心在
3楼-- · 2019-04-09 22:40

Looks like my problem was using "MM/DD/yyyy" when I should have used "MM/dd/yyyy". Uppercase D is "Day in year", while lowercase d is "Day in month".

new SimpleDateFormat("MM/dd/yyyy").parse(dateString);

Does the job. Also, "M/d/y" works interchangeably. A closer reading of the SimpleDateFormat API Docs reveals the following:

"For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields."

查看更多
对你真心纯属浪费
4楼-- · 2019-04-09 22:42

Yep, use setLenient:

DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
df.setLenient(true);
System.out.println(df.parse("05/05/1999"));
System.out.println(df.parse("5/5/1999"));
查看更多
登录 后发表回答