在java中解析字符串到日期格式默认为1和月到1月

我试图接受日期的用户输入,格式如:“2000小时,星期四,2015年7月20日”。 然后我会将其转换为日期格式以对其进行操作。 但是从字符串到日期的转换是默认月份到1月,日期为1.这是代码片段:

String userDateFormat = "HHmm 'hrs', EEEE, MMMM dd, YYYY"; SimpleDateFormat userDateFormatter = new SimpleDateFormat(userDateFormat); String reference_date = "2000 hrs, Thursday, July 20, 2015"; Date date = null; try { date = userDateFormatter.parse(reference_date); } catch (ParseException e) { System.out.println("Date must be in the format " + userDateFormat); } System.out.println(userDateFormatter.format(date)); 

以下方法块打印:2015年1月1日星期四,2000小时。任何线索为什么?

因为你在需要yyyy时使用YYYY ,2015年7月20日是星期一。 你想要的东西

 String userDateFormat = "HHmm 'hrs', EEEE, MMMM dd, yyyy"; SimpleDateFormat userDateFormatter = new SimpleDateFormat( userDateFormat); String reference_date = "2000 hrs, Monday, July 20, 2015"; 

然后输出

 2000 hrs, Monday, July 20, 2015 

然后SimpleDateFormat Javadoc说(部分)

 Letter Date or Time Component Presentation Examples G Era designator Text AD y Year Year 1996; 96 Y Week year Year 2009; 09 

java.time

  DateTimeFormatter userDateTimeFormatter = DateTimeFormatter.ofPattern("HHmm 'hrs', EEEE, MMMM dd, uuuu", Locale.ENGLISH); String referenceDate = "2000 hrs, Monday, July 20, 2015"; LocalDateTime dateTime = LocalDateTime.parse(referenceDate, userDateTimeFormatter); System.out.println(dateTime.format(userDateTimeFormatter)); 

输出是:

2015年7月20日(星期一)

Elliott Frisch的回答是正确的。 我正在使用现代Java日期和时间API java.time提供现代答案。 当问到这个问题时,已经有一年半了。 现在它已经四年了,而且很普遍。 我还提供了一个明确的语言环境。 您的日期时间是英语,而您的默认语言环境可能也是如此,如果有一天您在不同语言环境中的计算机上运行它或者您只是更改自己的语言环境设置,那么依赖于它的代码将会中断。

你是唯一一个在格式模式字符串中使用不正确的大小写错误的人。 有关此问题的问题一直在Stack Overflow上提出。 SimpleDateFormat以表现而闻名:它会给你一个不正确的结果,假装一切都很好,你真的希望它通知你出错了,例如抛出exception。

当您为其提供可以检测到的错误输入时,现代API 引发exception。 例如:

  DateTimeFormatter userDateTimeFormatter = DateTimeFormatter.ofPattern("HHmm 'hrs', EEEE, MMMM dd, YYYY", Locale.ENGLISH); String referenceDate = "2000 hrs, Thursday, July 20, 2015"; 

结果:

java.time.DateTimeException:无法从TemporalAccessor获取LocalDate:{MonthOfYear = 7,DayOfWeek = 4,WeekBasedYear [WeekFields [SUNDAY,1]] = 2015,DayOfMonth = 20},ISO解析为java.time类型的20:00 .format.Parsed

它不太可读。 需要注意的是“WeekBasedYear”。 基于周的年份仅适用于周数,所以这里错了。 而且文档会告诉你, YYYY是大写的YYYY 。 我们来修理:

  DateTimeFormatter userDateTimeFormatter = DateTimeFormatter.ofPattern("HHmm 'hrs', EEEE, MMMM dd, uuuu", Locale.ENGLISH); 

使用DateTimeFormatter ,习惯使用uuuu一年。 yyyy在0年后也工作了很多年。尽管如此,我们还没有完成:

java.time.DateTimeException:发现冲突:Field DayOfWeek 1与DayOfWeek 4不同,源自2015-07-20

现代API也拒绝接受一周中不正确的日期,因此您可以完全validation您的日期(但是,如果您不想进行此validation,则可以使用它来说服它)。 正如Elliott Frisch所说,2015年7月20日是星期一(本周的第1天),而不是星期四。 在我上面的第一个片段中,我也修复了这个错误,这样才行。

链接: Oracle教程:Date Time解释如何使用java.time