Java SimpleDateFormat解析错误的日期

我正在尝试使用SimpleDateFormat的解析函数将String转换为Date

  SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-YYYY"); String strInput1 = "29-04-2014"; System.out.println("string 1: " + strInput1); Date date1 = new Date(); try { date1 = sdf.parse(strInput1); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("date 1: " + date1.toString()); String strInput2 = sdf.format(date1); System.out.println("string 2: " +strInput2); Date date2 = new Date(); try { date2 = sdf.parse(strInput2); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("date 2 " + date2); 

date1的输出是Mon Dec 30 00:00:00 GMT 2013 ,然后正确解析为30-12-2014

我认为当sdf被初始化时,错误就在某处。

你正在使用YYYY这是一周 。 你的意思是yyyy ,这是一年

只需将您的格式更改为:

 SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); 

YYYY格式说明符很少使用,在使用时,它应与E / u (星期几的名称/数字)和w (星期的一周)一起使用。

请注意,您还应该考虑设置SimpleDateFormat的时区…另外,如果您使用的是Java 8,请使用java.time包,否则Joda Time是比java.util.Date等更清晰的库。 。

JSR-310中定义的现代Java数据和时间API几乎是在问这个问题的时候出现的,所以我认为现在是时候回答它了。 为了示例和解释,我们首先尝试保留不正确的格式模式字符串:

  DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-YYYY"); String strInput1 = "29-04-2014"; System.out.println("string 1: " + strInput1); LocalDate date1 = LocalDate.parse(strInput1, dtf); System.out.println("date 1: " + date1.toString()); 

解析strInput1的尝试给出了java.time.format.DateTimeParseException: Text '29-04-2014' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {DayOfMonth=29, MonthOfYear=4, WeekBasedYear[WeekFields[SUNDAY,1]]=2014},ISO of type java.time.format.Parsed 。 一方面,我认为例外是向前迈出的一步,而不是像你所经历的那样产生错误的日​​期。 另一方面,如果没有更深入的新类知识,exception消息就不容易阅读。 需要注意的是“WeekBasedYear”。 这仅适用于周数,因此将其视为错误的标志。 然后与文档进行比较。 它说u是年份,小写y代表年份,大写Y代表基于星期的年份。 假设一年将永远处于共同时代(“anno domini”),我们可以接受u或者y

  DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-uuuu"); 

现在代码打印:

 string 1: 29-04-2014 date 1: 2014-04-29 

我们还可以将日期格式化为字符串,当然:

  String strInput2 = date1.format(dtf); System.out.println("string 2: " +strInput2); 

结果是我们开始的字符串,如预期的那样:

 string 2: 29-04-2014 

请注意,现代API附带了一个LocalDate类,用于没有时间的日期。 在这种情况下,这可以更精确地模拟您的需求,并避免因在Date对象中拖动时间而导致的各种角落情况。

问题:我可以在Java 7中使用它吗? 你当然可以。 对于Java 6和7,获取ThreeTen Backport并开始使用现代类。