为什么Java date API(java.util.Date,.Calendar)如此混乱?

sle*_*ske 60 java api-design date

正如大多数人现在痛苦地意识到的那样,用于处理日历日期的Java API(特别是类java.util.Datejava.util.Calendar)是一个糟糕的混乱.

脱离我的头顶:

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

这篇文章总结得很好,JSR-310也解决了这些问题.

现在我的问题是:

这些类是如何进入Java SDK的?大多数这些问题看起来相当明显(特别是Date是可变的)并且应该很容易避免.那怎么回事?时间压力?或者回想起来的问题是否明显?

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

gus*_*afc 42

有人说它比我说的要好:

  • Class Date表示特定的时刻,精度为毫秒.这个类的设计是一个非常糟糕的笑话 - 一个令人清醒的例子,即使是优秀的程序员也会搞砸.现在不推荐使用Date中的大多数方法,而是使用下面类中的方法.
  • Class Calendar是一个抽象类,用于在Date 对象和一组整数字段(如年,月,日和小时)之间进行转换.

  • Class GregorianCalendarCalendarJDK中唯一的子类.它为常用的日历系统执行日期到字段的转换.Sun从Taligent获得了这个过度设计的垃圾 - 这是一个平均程序员如何搞砸的一个令人警醒的例子.

来自Java程序员常见问题解答,版本来自07.X.1998,作者Peter van der Linden - 虽然这部分已从以后的版本中删除.

至于可变性,很多早期的JDK类的遭受它(Point,Rectangle,Dimension,...).错误的优化,我听到有人说.

我们的想法是,您希望能够重用objects(o.getPosition().x += 5)而不是o.setPosition(o.getPosition().add(5, 0))像使用immutable一样创建副本().对于早期的虚拟机来说,这甚至可能是一个好主意,而最有可能的不是现代虚拟机.

  • 哈,来这里发帖吧!无法编辑您的帖子(需要更多代表)但是:"...日期代表特定的时刻,精确到毫秒级.这个类的设计是一个非常糟糕的笑话 - 一个令人清醒的例子,即使是优秀的程序员也搞砸了[...] GregorianCalendar是JDK中Calendar的唯一子类.[...] Sun从Taligent获得了这个过度设计的垃圾 - 这是一个关于普通程序员如何搞砸的一个严肃的例子."来自Peter van Der Linden的comp.lang.java .programmers"Java Programmer's FAQ",网址为http://www.faqs.org/faqs/computer-lang/java/programmers/faq/ (10认同)
  • @sleske:有趣的是,似乎FAQ一次性更改以删除引用.比较之前的版本(曾经在该链接中生效),http://www.cs.colorado.edu/~karl/APlus/javafaq.html(参见第5.8节),其中包含上述引用,版本I链接到 - 其中还说"感谢完全重写本部分的Paul Hill,以及IBM实施大部分Java Date代码的程序员,并回顾了FAQ的这一部分的准确性." 这对我来说听起来很可疑,就像有人不喜欢这种特征.:) (5认同)
  • 我喜欢这句话. (3认同)

cle*_*tus 20

Java的早期API只不过是他们时代的产物.在此之后几年,不变性才成为一种流行的概念.你说不变性是"显而易见的".现在可能是这样,但事实并非如此.就像依赖注入现在"显而易见"但不是10年前.

创建Calendar对象的费用也很高.

出于向后兼容的原因,它们仍然是这样.或许更不幸的是,一旦错误得以实现,旧的类没有被弃用,并且为所有API提供了新的日期/时间类.这在某种程度上发生在JDK 8采用JodaTime之类的API(java.time,JSR 310),但实际上它太晚了.


dz.*_*dz. 8

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

我记得,当我第一次看到java.util.Date(JDK 1.0?)时,我真的很开心.我所知道的语言没有这样的功能.我没有想过时间转换等.

我认为这很糟糕,因为如果你从一个理解水平(XMLGregorianCaldender vs. Date)和需求(纳秒,过去2030)发展到更高水平,但保持旧的不变,那么所有变化都会变得一团糟.并且java.util.Date不是Exception.只需看看I/O子系统或从AWT到Swing的过渡......

因此,"我们有时应该按下重置按钮." (谁说,顺便说一句.?)


Jes*_*run 5

您可能会发现以下帖子很有趣.它几乎解释了Calendar类如何首先进入Java API,并阐明了日期类的起源.

高度功能失调设计的七大习惯