设置上周周一0点的Calendar对象,却返回中午12点的时间,问题排查
设置上周周一0点的Calendar对象,却返回中午12点的时间,问题排查
嗨,你遇到的这个问题其实是Calendar类里12小时制和24小时制字段混淆导致的,咱们一步步理清楚:
核心问题:用错了时间字段
你代码里用calendar.set(Calendar.HOUR, 0)来设置0点,但Calendar.HOUR是12小时制的字段(取值范围0-11,对应上午12点到上午11点,或者下午12点到下午11点,取决于Calendar的AM/PM标记)。如果当前Calendar的AM/PM状态是PM,设置HOUR为0就会变成中午12点,这就是你看到结果为12:00:00的原因。
要设置24小时制的午夜0点,你需要用Calendar.HOUR_OF_DAY字段,它的取值范围是0-23,设置为0就明确代表当天的0点,不受AM/PM影响。
修正后的代码
先把时间设置的部分改对,同时也可以优化一下你计算上周一的逻辑,让代码更简洁:
Calendar calendar = Calendar.getInstance(); calendar.setTime(currentDate); // 计算需要往前推几天到上周一 Integer dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); int daysToSubtract = (dayOfWeek - Calendar.MONDAY + 7) % 7; // 如果今天就是周一,要减去7天得到上周一(如果需求是不管今天周几都取"上周"的周一) if (daysToSubtract == 0) { daysToSubtract = 7; } calendar.add(Calendar.DATE, -daysToSubtract); // 重置时间到0点——关键修改用HOUR_OF_DAY calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.HOUR_OF_DAY, 0); // 替换原来的HOUR字段 Date toDate = calendar.getTime();
额外建议:使用Java 8+的新时间API
Calendar类是Java旧版的时间API,设计上容易出现这类混淆问题,推荐你使用Java 8及以上版本的java.time包,代码更直观且不易出错:
// 把旧的Date转成LocalDateTime(适配当前系统时区) LocalDateTime currentLocal = currentDate.toInstant() .atZone(ZoneId.systemDefault()) .toLocalDateTime(); // 获取上周一的0点(如果今天是周一,previousOrSame会返回今天,要取上周的话就用previous(DayOfWeek.MONDAY)) LocalDateTime lastMondayMidnight = currentLocal.with(TemporalAdjusters.previous(DayOfWeek.MONDAY)) .truncatedTo(ChronoUnit.DAYS); // 再转回Date类型(如果业务需要的话) Date toDate = Date.from(lastMondayMidnight.atZone(ZoneId.systemDefault()).toInstant());
备注:内容来源于stack exchange,提问作者Alex A.
相关产品推荐
相关产品推荐

