Calendar 的 add 强制修改毫秒数的坑

In addition, unlike set(), add() forces an immediate recomputation of the calendar's milliseconds and all fields.

另外,与set()不同,add()强制立即重新计算日历的毫秒数和所有字段。

问题: java的文档是这样说的,但是发现并未重新计算毫秒数。

原因: 使用的 calender 是通过Calendar.getInstance();获取的,而这样获取的 calender 中重新计算的方法是抽象的。所以相当于并未重新计算。

解决: 不能获取抽象类 Calender,而应该获取实现了重新计算方法的 Calender 的子类。例如:Calendar calendar = new GregorianCalendar();

同时也印证了,如果要继承抽象类 Calendar,必须实现其重新计算这些方法。

详解:

重新计算日历的毫秒数和所有字段,调用的是 Calendar 中的 updateTime();方法。

/**
 * Recomputes the time and updates the status fields isTimeSet
 * and areFieldsSet.  Callers should check isTimeSet and only
 * call this method if isTimeSet is false.
 */
private void updateTime() {
    computeTime();
    // The areFieldsSet and areAllFieldsSet values are no longer
    // controlled here (as of 1.5).
    isTimeSet = true;
}

又调用了computeTime();方法,但是在 Calendar 抽象类中,computeTime();方法是抽象的,所以即使执行了add()之类的方法也不会更新到毫秒数。

/**
 * Converts the current calendar field values in {@link #fields fields[]}
 * to the millisecond time value
 * {@link #time}.
 *
 * @see #complete()
 * @see #computeFields()
 */
protected abstract void computeTime();

e.g.

Calendar calendar = Calendar.getInstance();         //---------------这是重点
System.out.println("原始一日历 calendar:" + calendar.getTime());
System.out.println("年YEAR: " + calendar.get(Calendar.YEAR));
System.out.println("月MONTH: " + calendar.get(Calendar.MONTH));
System.out.println("日DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分MINUTE: " + calendar.get(Calendar.MINUTE));
System.out.println("秒SECOND: " + calendar.get(Calendar.SECOND));
System.out.println("其毫秒数: " + calendar.getTimeInMillis());
calendar.add(Calendar.SECOND, 1);
System.out.println("被加了一秒的日历 calendar: " + calendar.getTime());
System.out.println("年YEAR: " + calendar.get(Calendar.YEAR));
System.out.println("月MONTH: " + calendar.get(Calendar.MONTH));
System.out.println("日DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分MINUTE: " + calendar.get(Calendar.MINUTE));
System.out.println("秒SECOND: " + calendar.get(Calendar.SECOND));
System.out.println("其毫秒数: " + calendar.getTimeInMillis());

out:

原始一日历 calendar:Wed Jan 03 17:06:27 CST 2018
年YEAR: 2018
月MONTH: 0
日DAY_OF_MONTH: 3
时HOUR_OF_DAY: 17
分MINUTE: 6
秒SECOND: 27
其毫秒数: 1514970387917         //---------------这是重点
被加了一秒的日历 calendar: Wed Jan 03 17:06:28 CST 2018
年YEAR: 2018
月MONTH: 0
日DAY_OF_MONTH: 3
时HOUR_OF_DAY: 17
分MINUTE: 6
秒SECOND: 28
其毫秒数: 1514970388917         //---------------这是重点

说明:虽然其字段的值已经改变,但是毫秒数并未重新计算

但当在继承了 Calendar 的子类中:

e.g.

Calendar calendar = new GregorianCalendar();         //---------------这是重点
System.out.println("原始一日历 calendar:" + calendar.getTime());
System.out.println("年YEAR: " + calendar.get(Calendar.YEAR));
System.out.println("月MONTH: " + calendar.get(Calendar.MONTH));
System.out.println("日DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分MINUTE: " + calendar.get(Calendar.MINUTE));
System.out.println("秒SECOND: " + calendar.get(Calendar.SECOND));
System.out.println("其毫秒数: " + calendar.getTimeInMillis());
calendar.add(Calendar.SECOND, 1);
System.out.println("被加了一秒的日历 calendar: " + calendar.getTime());
System.out.println("年YEAR: " + calendar.get(Calendar.YEAR));
System.out.println("月MONTH: " + calendar.get(Calendar.MONTH));
System.out.println("日DAY_OF_MONTH: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时HOUR_OF_DAY: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分MINUTE: " + calendar.get(Calendar.MINUTE));
System.out.println("秒SECOND: " + calendar.get(Calendar.SECOND));
System.out.println("其毫秒数: " + calendar.getTimeInMillis());

out:

原始一日历 calendar:Wed Jan 03 16:30:46 CST 2018
年YEAR: 2018
月MONTH: 0
日DAY_OF_MONTH: 3
时HOUR_OF_DAY: 16
分MINUTE: 30
秒SECOND: 46
其毫秒数: 1514968246589         //---------------这是重点
被加了一秒的日历 calendar: Wed Jan 03 16:30:47 CST 2018
年YEAR: 2018
月MONTH: 0
日DAY_OF_MONTH: 3
时HOUR_OF_DAY: 16
分MINUTE: 30
秒SECOND: 47
其毫秒数: 1514968247589         //---------------这是重点

你可能感兴趣的:(Calendar 的 add 强制修改毫秒数的坑)