Calendar.Hour
vsCalendar.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.HOUR
,Calendar.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);
}