Java Spring Boot中new Date为何返回Tomcat启动日期而非当前日期
问题根因说明
你观察到的返回值始终固定为Tomcat启动日期的现象,和toCalendar方法本身的计算逻辑没有直接关联,核心触发点和可修正的小问题如下:
- 最常见的触发场景:将
todayWithNoTime的计算结果定义为Spring单例Bean的成员变量、类静态变量,赋值动作发生在类加载、Bean初始化的Tomcat启动阶段,后续所有业务逻辑拿到的都是启动时预先算好的固定值,不会在每次运行时重新执行new Date()的计算逻辑。 - 方法本身的冗余设计:代码中同时设置了
Calendar.HOUR(12小时制字段)和Calendar.HOUR_OF_DAY(24小时制字段)两个时间维度,两个字段会互相覆盖取值,在服务器时区配置存在差异的场景下可能出现时间偏移,但不会直接导致日期固定不变。
修正方案
- 首先清理方法内的冲突代码,删除冗余的12小时制字段设置,仅保留24小时制的时间清零逻辑,避免字段互相覆盖:
public static Calendar toCalendar(Date date) { Calendar cal = Calendar.getInstance(); cal.setTime(date); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); return cal; }
- 调整结果的存储逻辑:每次需要获取当前日期的零点值时,必须在业务方法内部临时调用上述方法计算,不要将计算结果缓存为类成员变量、静态变量,更不要在Bean初始化阶段提前赋值。
- 可选优化:如果运行环境为Java 8及以上版本,可以替换老旧的
Date/Calendar实现,使用线程安全、设计更稳定的java.time包下的API实现同等功能,从根源避免字段冲突问题:
// 获取当前系统时区下的当天零点Date对象 Date todayStart = Date.from( LocalDate.now() .atStartOfDay(ZoneId.systemDefault()) .toInstant() );
内容的提问来源于stack exchange,提问作者Newbie83
相关产品推荐
相关产品推荐

