为何使用SimpleDateFormat格式化再解析同一日期会得到不同结果?
问题描述
代码示例:
SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMDD"); logger.info("new Date()="+new Date()); Date today = sdf.parse(sdf.format(new Date())); logger.info("today:"+today + ", today.getTime():" + today.getTime());
执行结果:
new Date()=Fri Sep 30 09:45:07 HKT 2022
today:Sun Dec 26 00:00:00 HKT 2021, today.getTime():1640448000000
为何使用SimpleDateFormat对同一日期先格式化再解析后,得到的日期与原日期不一致?
问题原因
核心是用错了两个日期格式符:
YYYY不是常规日历年:它代表「周年(Week Year)」,即当前日期所在周归属的年份,规则是一周默认从周日开始,整个周会被归到包含该周更多天数的年份中,和我们日常用的日历年(yyyy)逻辑完全不同。DD不是当月天数:它代表「一年中的第几天」,而非「当月的第几天」(后者是dd)。
你的代码用YYYYMMDD格式化日期时,生成的字符串是「周年+月份+年中天数」的组合,但解析时SimpleDateFormat会把这个字符串按「日历年+月份+年中天数」去处理,三者逻辑不匹配,最终导致解析出完全偏离原日期的结果。
解决方法
改用标准的日历年+月份+当月天数格式:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); logger.info("new Date()="+new Date()); Date today = sdf.parse(sdf.format(new Date())); logger.info("today:"+today + ", today.getTime():" + today.getTime());
这样格式化再解析后,日期会和原日期一致(仅时间部分会被置为0,因为格式化只保留了日期信息)。
另外更推荐使用Java 8+的java.time包(线程安全、逻辑更清晰):
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDate now = LocalDate.now(); LocalDate parsedDate = LocalDate.parse(now.format(formatter), formatter); System.out.println("now: " + now); System.out.println("parsedDate: " + parsedDate);
内容的提问来源于stack exchange,提问作者user1169587
相关产品推荐
相关产品推荐

