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并开始使用现代类。