为什么JavadateAPI(java.util.Date,.Calendar)这么乱?

由于现在大多数人都痛苦地意识到,处理日历date的Java API(特别是类java.util.Datejava.util.Calendar )是一个非常糟糕的混乱。

closures我的头顶上:

  • date是可变的
  • date代表时间戳,而不是date
  • 没有简单的方法来转换date组件(日,月,年…)和date
  • 日历是笨重的使用,并试图将不同的日历系统合并成一个类

这篇文章总结得非常好, JSR-310也解决了这些问题。

现在我的问题是:

这些类是如何进入Java SDK的? 这些问题大部分似乎相当明显(特别是date可变),应该很容易避免。 那么这是怎么发生的? 时间压力? 还是仅仅是回想起来的问题?

我意识到这不是一个严格的编程问题,但是我会发现理解APIdevise如何错误是有趣的。 毕竟,错误总是一个很好的学习机会(我很好奇)。

有人把它比我所能说的更好:

  • Date表示特定的即时时间,精度为毫秒。 这个课程的devise是一个非常糟糕的玩笑 – 一个好的程序员如何搞砸的例子。 Date中的大多数方法现在都被弃用了,被下面的类中的方法所取代。
  • Calendar是一个抽象类,用于在Date对象和一组整数字段(如年,月,日和小时)之间进行转换。

  • GregorianCalendar是JDK中Calendar的唯一子类。 它为常用的日历系统进行date到字段的转换。 Sun从Taligent那里获得了这个过度工程的垃圾许可 – 这是一个普通程序员如何搞砸的清醒例子。

Java程序员常见问题 ,由Peter van der Linden发布于07.X.1998,但是这个部分已经从后来的版本中删除了。

至于可变性,很多早期的JDK类受到它( PointRectangleDimension …)的影响。 错误的优化,我听到了一些说。

这个想法是,你想能够重用对象( o.getPosition().x += 5 ),而不是像你一样创build副本( o.setPosition(o.getPosition().add(5, 0)) )与不可变的事情做。 对于早期的虚拟机,这甚至可能是一个好主意,而最有可能的不是现代虚拟机。

Java早期的API只不过是他们时代的产物。 在此之后的几年里,不变性才成为一个stream行的概念。 你说不变性是“显而易见的”。 现在可能是这样,但现在不是。 就像dependency injection现在是“显而易见的”,但它不是10年前。

创buildCalendar对象的时间也很昂贵。

为了向后兼容的原因,他们仍然是这样的。 也许更不幸的是,一旦错误被实现,旧的类别不被弃用,并且为所有API前进创build新的date/时间类别。 这在一定程度上发生在JDK 8采用类似API的JodaTime( java.time ,JSR 310)之后,但实际上太迟了。

时间本身并不容易衡量和处理。 只要看看维基百科有关时间的文章的长度。 然后,对时间本身有不同的理解:一个绝望的时间点(作为一个常数),一个特定的时间点,一个时间范围,时间的分辨率….

我记得,当我第一次看到java.util.Date(JDK 1.0?)时,我真的很高兴。 我所知道的语言没有这样的特点。 我没有考虑时间转换等

我认为这是一团糟,因为如果你从一个层次的理解(XMLGregorianCaldender vs. Date)和要求(2030年前的Nanoseconds)发展到更高层次,但是保持旧的不变,所有的变化都会变得一团糟。 而java.util.Date不是一个例外。 看看I / O子系统或从AWT到Swing的转换…

因此,“有时我们应该按下重置button。” (谁说,顺便说一句?)

您可能会发现以下post有趣。 它很好地解释了Calendar类如何进入Java API,并且阐明了date类的起源。

高functiondevise的七种习惯