Calendar.set陷阱-Calendar.Hour&Calendar.Hour_of_day

Calendar.HourvsCalendar.Hour_of_day

        Calendar workCalendar = Calendar.getInstance();
        workCalendar.setTime(new Date(-10800000));
        Calendar calendar = Calendar.getInstance();;
        calendar.setTime(new Date());
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, workCalendar.get(Calendar.MINUTE));
        calendar.set(Calendar.HOUR, workCalendar.get(Calendar.HOUR));
        System.out.println(calendar.getTime().getTime()/1000);
        calendar.set(Calendar.HOUR_OF_DAY, workCalendar.get(Calendar.HOUR));
        System.out.println(calendar.getTime().getTime()/1000);

result is:

1571648400  (2019-10-21 17:00:00)
1571605200  (2019-10-21 05:00:00)

上面的例子,相同的时间在用calendar.set赋值分别用Calendar.HOURCalendar.HOUR_OF_DAY有不同的结果一个是17:00,一个是5:00

原因分析

Calendar.HOUR是12小时制,设置的值大于等于12时,得到的结果会是day+1,凌晨和中午都是0,不是12;需要配合Calendar.AM_PM使用;
Calendar.HOUR_OF_DAY是24小时制
为什么题主用Calendar.HOUR会取到17:00呢,这是由于Calendar.HOUR的另一个机制区分上午、下午参数Calendar.AM_PM导致的,题主当时系统时间是14:00下午,在第四行代码setTime的时候已经设置Calendar.PM(1)了,因此设置完calendar.set(Calendar.HOUR, 5)后又转化时间格式打印出的是17:00
setTime源码分析java.util.GregorianCalendar#computeFields(int, int):

   if ((fieldMask & (HOUR_OF_DAY_MASK|AM_PM_MASK|HOUR_MASK
                          |MINUTE_MASK|SECOND_MASK|MILLISECOND_MASK)) != 0) {
            if (timeOfDay != 0) {
                int hours = timeOfDay / ONE_HOUR;
                internalSet(HOUR_OF_DAY, hours);
                internalSet(AM_PM, hours / 12); // Assume AM == 0
                internalSet(HOUR, hours % 12);
                int r = timeOfDay % ONE_HOUR;
                internalSet(MINUTE, r / ONE_MINUTE);
                r %= ONE_MINUTE;
                internalSet(SECOND, r / ONE_SECOND);
                internalSet(MILLISECOND, r % ONE_SECOND);
            } else {
                internalSet(HOUR_OF_DAY, 0);
                internalSet(AM_PM, AM);
                internalSet(HOUR, 0);
                internalSet(MINUTE, 0);
                internalSet(SECOND, 0);
                internalSet(MILLISECOND, 0);
            }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容