4

有没有一种简单的方法来解析可能在 MM/DD/yyyy 或 M/D/yyyy 或某种组合中的日期?即,在一位数的日期或月份之前,零是可选的。

要手动完成,可以使用:

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

并通过以下方式验证:

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

是否有调用 SimpleDateFormat 或 JodaTime 来处理这个问题?

4

3 回答 3

11

是的,使用 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"));
于 2008-10-22T21:31:25.267 回答
2

java.time

Java 8 及更高版本包括 java.time 框架。该框架淘汰了此处其他答案中讨论的旧 java.util.Date/.Calendar 类。

java.time.format 包及其 java.time.format.DateTimeFormatter 类使用的模式代码类似于Ray Myers接受的答案中所见的模式代码。虽然相似,但它们略有不同。特别是他们对重复字符的数量非常严格。如果你说MM,那么月份必须填充零,否则你会得到DateTimeParseException。如果月份数字可能有也可能没有填充零,只需使用单字符M.

在此示例代码中,请注意输入字符串的月份编号如何填充零,而月份编号则没有。两者都由单字符模式处理。

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

转储到控制台。

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

本地日期:2015-01-02

于 2015-10-29T04:12:20.947 回答
1

看起来我的问题是使用“MM/DD/yyyy”,而我应该使用“MM/dd/yyyy”。大写的D是“年中的日”,而小写的d是“月中的日”。

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

做这项工作。此外,“M/d/y”可以互换使用。仔细阅读SimpleDateFormat API 文档会发现以下内容:

“对于解析,模式字母的数量被忽略,除非需要分隔两个相邻的字段。”

于 2008-10-23T02:35:25.887 回答