问题集锦

Calendar.set陷阱-Calendar.Hour&Cal

2019-10-21  本文已影响0人  五城十九洲

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);
            }
上一篇 下一篇

猜你喜欢

热点阅读