The class Date represents a specific instant in time, with millisecond precision.
这意味着 Date 是用来记录一个「瞬间」的而不是仅仅局限于记录年月日,甚至拥有毫秒级别的精度,但是与此同时 Date 类竟然并不是 final 的,这意味着开发者还可以通过 setTime() 去改变「瞬间」。除此之外,开发者甚至可以创建1月32日这样的日期——new Date(2018, 0, 32),打印结果会告诉你它是2月1日—— Fri Feb 01 00:00:00 CST 3918,Java
“聪明地”帮开发者修复了 bug。除此之外,即使 Date 作为记录「瞬间」的类,它也仍然是不合格的,根据常识可以知道,衡量一个瞬间除了记录年月日时分秒之外,还应该记录时区,但是 Date 对象中并没有包含时区这个关键属性,而仅仅是在 toString() 方法中 new 了一个时区对象并打印出来,这明显是不符合常理的,举个例子——
在北京的开发者将一篇周报发给了在华盛顿的老总,这篇周报使用了一个 Date 对象来记录周报的创建日期,远在华盛顿的老总清早地没刷牙就打开周报,最后发现底部的日期为 Sat Aug 04 17:35:24 PDT 2018,于是他大发雷霆质问北京的开发者,你的周报创建时间为什么是美国时间8月4日17点35分(PDT 时区),明明现在的美国时间是8月4日5点35分!远在中国的开发者看了看周报的日期,底部毅然写着 Sat Aug 04 17:35:24
CST 2018,这明明是北京时间8月4日17点35分(CST 时区),为什么到了美国就成了美国时间8月4日17点35分了呢?答案就是在于 toString() 方法中的时区是取得当前系统默认的时区,在北京应该就是北京时间8月4日17点35分,在华盛顿就是美国时间8月4日17点35分。所以问题就在于时区这个属性并没有在创建对象的时候就赋值并后期不可改,而是在 toString() 的时候去动态创建,这就造成了上面的误解。
以上令人困惑的设计真是糟糕透顶了!
当然,机智的读者可能早就意识到了,Date 注释当中已经提及到了——使用 java.util.Calendar 类来替代 Date 当中部分过时的方法。是的,早在 JDK1.1 版本的时候,语言的设计者们就意识到了这个问题,并创建了 Calendar 类来弥补 Date 类中的许多方法的缺陷,但是 Calendar 真的解决了问题吗?