提问人:Anton Gogolev 提问时间:12/28/2009 最后编辑:Piper BarrettAnton Gogolev 更新时间:2/4/2021 访问量:34828
Java Date & Time API 有什么问题?[已结束]
What's wrong with Java Date & Time API? [closed]
问:
我经常遇到关于Java和其他与日期时间相关的类的负面反馈。作为一名 .NET 开发人员,我无法完全(没有使用过它们)理解它们到底有什么问题。Date
谁能对此有所了解?
答:
我为你感到难过......作为一名前 .NET 程序员,我问了同样的问题,.NET 中的时间 API(时间跨度、运算符重载)非常方便。
首先,若要创建特定日期,请使用已弃用的 API,或者:
Calendar c = Calendar.getInstance();
c.set(2000, 31, 12)
为了减去一天,你做了坏事,比如
Date firstDate = ...
Calendar c = Calendar.getInstance();
c.setTime(fistDate);
c.add(Calendar.DATE,-1);
Date dayAgo = c.getTime();
或更糟
Date d = new Date();
Date d2 = new Date(d.getTime() - 1000*60*60*24);
要了解两个日期之间经过了多少时间(以天/周/月为单位)...情况变得更糟
但是,apache () 的 DateUtils 提供了一些方便的方法,我发现自己最近只使用它们org.apache.commons.lang.time.DateUtils
正如 Brabster 所写,Joda Time 也是一个很好的外部库,但 apache 似乎比其他任何东西都更“常见”......
评论
- 日期实例是可变的,这几乎总是不方便的。
- 他们有双重性质。它们表示时间戳和日历日期。事实证明,在对日期进行计算时,这是有问题的。
- 在许多情况下,日历数据的数字表示是违反直觉的。例如:从零开始,从 1900 年开始(即 2009 年表示为 109)。
getMonth()
getYear()
- 它们缺少您期望从类中获得的许多功能。
Date
老实说,我发现 Java 的 Date API 是可用的。我所看到和听到的大多数问题都与冗长、需要涉及多个类来做任何有用的事情 (, , /) 以及缺乏像 .Calendar
Date
DateFormat
SimpleDateFormat
getDayOfWeek()
Joda Time 是 Java 中一个备受推崇的替代 API,在 Why Joda Time 一节中,它给出了更多论据,说明为什么它是一个可能值得关注的可行替代方案。
JSR 310 在 Java 8 中用 java.time 取代了旧的日期时间类,在原始 JSR 中证明了自己的合理性,如下所示:
2.5 Java社区的需求将通过提议 规范?
目前,Java SE 有两个独立的 日期和时间 API - java.util.Date 和 java.util.Calendar。这两个 API 都是 一直被描述为难以 Java 开发人员在博客上使用 论坛。值得注意的是,两者都使用零索引 几个月来,这是许多人的原因 错误。日历也遭受了 许多错误和性能问题 岁月,主要是由于存储 它以两种不同的方式处于状态 内部。
一个经典错误(4639407)被阻止 从在 Calendar 对象。代码序列 可以写成可以创建一个 日期在某些年份,但在其他年份没有, 具有预防某些 用户输入正确的 出生日期。这是由 Calendar 类只允许 夏令时增益 1 小时 在夏天,历史上它是 加上 2 小时左右的时间 第二次世界大战。虽然这个错误是 现在已修复,如果在 未来一个国家选择引入一个 夏令时增益 夏天三个小时,然后 日历类将再次被打破。
当前的 Java SE API 也受到了影响 在多线程环境中。 已知不可变类是 本质上是线程安全的状态 无法更改。但是,Date 和 日历是可变的,这需要 程序员要考虑克隆和 显式线程。此外, 缺乏螺纹安全 DateTimeFormat 并不广为人知, 并一直是许多难以 跟踪线程问题。
以及 Java SE 为 datetime 提供的类, 它没有用于建模其他的类 概念。非时区日期或 时间、持续时间、期间和 间隔没有类表示 在 Java SE 中。因此,开发人员 经常使用 int 来表示 持续时间,使用 JavaDoc 指定单位。
缺乏一个全面的日期和 时间模型还导致许多常见的 操作比他们更棘手 应该是。例如,计算 两个日期之间的天数 是一个特别难的问题 目前。
这个 JSR 将解决 完整的日期和时间模型, 包括日期和时间(带有和 无时区)、持续时间和 时间段、间隔、格式 和解析。
啊,Java 类。也许是如何在任何地方不用任何语言做某事的最好例子之一。我从哪里开始?Date
阅读 JavaDoc 可能会让人认为开发人员实际上有一些好主意。它详细讨论了 UTC 和 GMT 之间的区别,尽管两者之间的差异基本上是闰秒(这种情况很少发生)。
然而,设计决策确实浪费了任何设计良好的 API 的想法。以下是一些最喜欢的错误:
- 尽管是在千禧年的最后十年设计的,但自 1900 年以来,它以两位数计算年份。由于这个平庸的决定,在 Java 世界中,有数百万种变通方法在做 1900+(或 1900-)。
- 月份是零索引,以迎合具有月份数组并且不使用 13 个元素数组的非常不寻常的情况,其中第一个数组包含 .结果,我们有 0..11(今天是 109 年的第 11 个月)。月份上有类似数量的 ++ 和 -- ,以便转换为字符串。
null
- 它们是可变的。因此,每当您想要返回日期时(例如,作为实例结构),您都需要返回该日期的克隆,而不是日期对象本身(因为否则,人们可以改变您的结构)。
- 旨在“修复”这个问题,实际上犯了同样的错误。它们仍然是可变的。
Calendar
Date
表示一个 ,但为了服从 SQL 领域中的那些,还有另一个子类 ,它表示一天(尽管没有与之关联的时区)。DateTime
java.sql.Date
- 没有与 关联的 s,因此范围(例如“一整天”)通常表示为午夜-午夜(通常在某些任意时区)
TimeZone
Date
最后,值得注意的是,闰秒通常会根据良好的系统时钟进行自我校正,该系统时钟会在一小时内用 ntp 更新(参见上面的链接)。在引入两个闰秒(至少每六个月一次,实际上每隔几年)中,系统仍然启动并运行的可能性很小,特别是考虑到您必须不时重新部署新版本的代码。即使使用重新生成类的动态语言或类似 WAR 引擎的东西也会污染类空间并最终耗尽 permgen。
评论