Calendar cal = Calendar.getInstance();
  cal.set(1999, 12, 31);
  System.out.println( cal.get(Calendar.YEAR) +"");

这三行代码的执行结果是什么?

是 1999 吗?

但是它没有,结果是 2000。是千年虫问题吗?

        事情比我们想象的还要糟糕:这是致命的 Date/Calendar 问题。在 Java 1.0 发布的时候,,它唯一支持的日历计算类就是 Date 类。由于这个类有许多的问题,因此,在 1.1 版的时候,Calendar 类被添加到 Java 中,以纠正 Date 的缺点,不幸的是,问题更多了。
 
        我们习惯上将第一个月当作 1,因此 12  可以用来表示 12 月,不幸的是,Date 的月份表示从 0 开始,因此 12 月将用 11 来表示,而且 Calendar 继续延续了这个错误。因此上面的代码将月份设置为了 13 月,但是实际的月份只有 12 个月,代码应该抛出一个异常,通知我们发生了什么,他应该这么做,可是,它没有,它直接认为这应该是下一个月,也就是 2000 年的 1 月。因此我们上面的代码输出结果为 2000。

Date d = cal.getTime();
System.out.println( d.getDay());

再看这两行代码的结果是什么?

是 31 吗?

结果是 1

        我们在前面将日期设为了 31 日,在 cal.getTime() 中返回了一个 Date 类型的日期,这个日期也应该是 31 ,为什么是 1 呢?

        还是查一下 JavaDoc 吧, Date.getDay 返回的实际上是日期的星期数,也就是返回的结果是星期几,而不是月份中的日期。这个值从星期天开始计算,从 0 开始,因此,打印 1  表示 2000年12月31日是星期一。注意一下吧, Calendar 的方法 get( Calendar.DAY_OF_WEEK) 不知道为什么返回的是基于 1 开始的星期日期,而不是基于 0 开始的星期日期。

    以上内容取自 《Java 解惑》 P144