Java 8 Date Time API (java.time) 和 Joda-Time 之间的区别

2022-08-31 05:12:07

我知道有一些与java.util.Date和Joda-Time有关的问题。但经过一番挖掘,我找不到关于java.time APIJava 8中的新内容,由JSR 310定义)和Joda-Time之间差异的线索。

我听说Java 8的java.time API要干净得多,可以比Joda-Time做得更多。但我找不到比较两者的例子。

  • java.time能做哪些Joda-Time做不到的事情?
  • java.time在哪些方面能比Joda-Time做得更好?
  • 使用java.time的性能更好吗?

答案 1

常见功能

a) 两个库都使用不可变类型。Joda-Time还提供了其他可变类型,例如.MutableDateTime

b)此外:这两个库的灵感都来自Eric Evans的设计研究“TimeAndMoney”Martin Fowler关于领域驱动风格的想法,因此它们或多或少地追求流畅的编程风格(尽管并不总是完美的;-))。

c)使用这两个库,我们得到一个真正的日历日期类型(称为),一个真正的墙时间类型(称为)和组合(称为)。与旧的和相比,这是一个非常大的胜利。LocalDateLocalTimeLocalDateTimejava.util.Calendarjava.util.Date

d) 两个库都使用以方法为中心的方法,这意味着它们鼓励用户使用而不是 .与 相比,这导致了许多额外的方法(尽管由于过度使用ints,后者根本不是类型安全的)。getDayOfYear()get(DAY_OF_YEAR)java.util.Calendar

性能

通过@OO7指向Mikhail Vorontsov的分析来查看另一个答案,尽管第3点(异常捕获)可能已经过时 - 请参阅此JDK错误。不同的性能(通常有利于JSR-310)主要是由于Joda-Time的内部实现总是使用类似机器时间的长原语(以毫秒为单位)。

Joda-Time 通常使用 NULL 作为系统时区、默认区域设置、当前时间戳等的默认值,而 JSR-310 几乎总是拒绝 NULL 值。

精度

JSR-310处理纳秒级精度,而Joda-Time则限制在毫秒级精度。

支持的字段:

有关Java-8(JSR-310)中受支持字段的概述由临时包中的一些类(例如ChronoFieldWeekFields)给出,而Joda-Time在这方面相当弱 - 请参阅DateTimeFieldType。Joda-Time最大的不足是缺乏本地化的周相关字段。这两种字段实现设计的一个共同特征是,两者都基于 long 类型的值(没有其他类型,甚至没有枚举)。

枚举

JSR-310提供了类似或Joda-Time的枚举,因为它主要是在Java 5之前的2002-2004年开发的。DayOfWeekMonth

区域接口

a) JSR-310 提供比 Joda-Time 更多的时区功能。后者无法以编程方式访问时区偏移转换的历史记录,而 JSR-310 能够执行此操作。

b) 供您参考:JSR-310 已将其内部时区存储库移动到新位置和不同格式。旧的库文件夹 lib/zi 不再存在。

调整器与属性

JSR-310 引入了 -interface 作为外部化时间计算和操作的形式化方法,特别是对于库或框架编写者来说,这是嵌入 JSR-310 新扩展的一种不错且相对简单的方法(一种等效于以前的静态帮助程序类)。TemporalAdjusterjava.util.Date

但是,对于大多数用户来说,此功能的价值非常有限,因为编写代码的负担仍然在用户身上。基于新概念的内置解决方案并没有那么多,目前只有具有有限操作集的帮助器类(以及枚举或其他时态类型)。TemporalAdjusterTemporalAdjustersMonth

Joda-Time提供了一个字段包,但实践表明,新的字段实现很难编码。另一方面,Joda-Time提供了所谓的属性,这使得一些操作比JSR-310更容易,更优雅,例如performance.withMaximumValue()。

日历系统

JSR-310 提供 4 个额外的日历系统。最有趣的是Umalqura(在沙特阿拉伯使用)。其他3个是:明国(台湾),日本(自1871年以来只有现代日历!)和泰国佛教(仅在1940年后正确)。

Joda-Time提供基于计算器基础的伊斯兰日历 - 而不是像Umalqura那样基于目击的日历。Joda-Time也以类似的形式提供泰国佛教,Minguo和日本人没有。否则Joda-Time也提供科普特和埃塞俄比亚历法(但没有任何国际化支持)。

对欧洲人来说更有趣:Joda-Time还提供公历儒略历和混合公历 - 儒略历。但是,实际历史计算的实际价值是有限的,因为根本不支持诸如日期历史记录中不同年份开始之类的重要特征(相同的批评也适用于旧)。java.util.GregorianCalendar

希伯来语波斯语印度教等其他日历在两个图书馆中都完全缺失。

纪元日

JSR-310具有JulianFields类,而Joda-Time(版本2.0)在DateTimeUtils类中提供了一些帮助器方法。

时钟

JSR-310没有接口(设计错误),而是一个抽象类,可用于任何时钟依赖注入。Joda-Time在DateTimeUtils中提供了MillisProvider接口和一些帮助器方法。因此,通过这种方式,Joda-Time还能够支持具有不同时钟(模拟等)的测试驱动模型。java.time.Clock

持续时间算术

这两个库都支持以一个或多个时间单位计算时间距离。但是,在处理单单位持续时间时,JSR-310 样式显然更好(并且基于长而不是使用 int):

JSR-310 =>long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Time =>int days = DAYS.daysBetween(date1, date2).getDays();

处理多个单元持续时间也不同。甚至计算结果也可能不同 - 请参阅此已关闭的Joda-Time问题。虽然 JSR-310 使用非常简单且有限的方法仅使用类(基于年、月和日的持续时间)和(基于秒和纳秒),但 Joda-Time 使用更复杂的方法来使用类来控制持续时间(Joda-Time 称之为“周期”)应以何种单位表示。虽然使用类似的方式有点尴尬,但JSR-310根本没有提供。特别是在 JSR-310 中,还不可能定义混合日期和时间持续时间(例如基于天和小时)。因此,如果涉及从一个库到另一个库的迁移,请发出警告。讨论中的库是不兼容的 - 尽管类名部分相同。PeriodDurationPeriodTypePeriodType

间隔

JSR-310 不支持此功能,而 Joda-Time 的支持有限。另请参阅此 SO-answer

格式化和分析

比较这两个库的最佳方法是查看同名类 DateTimeFormatterBuilder (JSR-310) 和 DateTimeFormatterBuilder (Joda-Time)。JSR-310变体功能更强大(如果现场实现者设法编写了一些扩展点(如resolve()),也可以处理任何类型的扩展)。然而,在我看来,最重要的区别是:TemporalField

JSR-310可以更好地解析时区名称(格式模式符号z),而Joda-Time在其早期版本中根本无法做到这一点,现在只能以非常有限的方式做到这一点。

JSR-310的另一个优点是支持独立的月份名称,这在俄语或波兰语等语言中很重要。Joda-Time无法访问此类资源 - 即使在Java-8平台上也是如此。

JSR-310 中的模式语法也比 Joda-Time 中的模式语法更灵活,允许使用可选部分(使用方括号),更面向 CLDR 标准,并提供填充(字母符号 p)和更多字段。

否则应该注意的是,Joda-Time可以使用CiementFormatter格式化持续时间。JSR-310 无法做到这一点。


希望此概述有所帮助。所有收集的信息主要是由于我的努力和调查如何设计和实现一个更好的日期和时间库(没有什么是完美的)。

2015-06-24更新:

同时,我找到了时间,用Java编写和发布不同时间库的表格概述。这些表还包含Joda-Time v2.8.1和Java-8(JSR-310)之间的比较。它比这篇文章更详细。


答案 2

Java 8 日期/时间 :

  1. Java 8 类是围绕人类时间构建的。它使它们能够快速进行人类日期时间算术/转换。
  2. 日期/时间组件 getter 在 Java 8 实现中具有 O(1) 复杂性。getDayOfMonth
  3. 在 Java 8 ea b121 中,解析 // 非常慢,因为在 JDK 中内部抛出并捕获了异常。OffsetDateTimeOffsetTimeZonedDateTime
  4. 一组包:、、、、java.time.*java.time.chrono.*java.time.format.*java.time.temporal.*java.time.zone.*
  5. 即时(时间戳) 日期和时间 部分日期和时间解析器和格式化程序 时区 不同的时间顺序(日历)。
  6. 现有类存在日期不支持 I18N 或 L10N 等问题。他们是可变的!
  7. 更简单,更强大。
  8. 可以注入时钟。
  9. 时钟可以创建具有各种属性 - 静态时钟,模拟时钟,低精度时钟(整秒,整分钟等)。
  10. 可以使用特定时区创建时钟。.Clock.system(Zone.of("America/Los_Angeles"))
  11. 使代码处理日期和时间可测试。
  12. 使测试独立于时区。

上田时间 :

  1. Joda-Time在里面使用机器时间。基于整型/长整型值的手动实现会快得多。
  2. Joda-Time getters需要对每个getter调用进行计算机到人的时间计算,这使得Joda-Time成为此类情况下的瓶颈。
  3. 它由不可变的类组成,它处理即时,日期和时间,部分和持续时间 它是灵活的 它设计得很好。
  4. 将日期表示为即时。但是一个日期和时间可能对应于多个时刻。与夏令时结束的小时重叠。以及根本没有任何与之对应的瞬间。日照开始时的间隔时间。必须为简单操作执行复杂的计算。
  5. 在其大多数方法上接受 null 作为有效值。导致微妙的错误。

有关更详细的比较,请参阅:-

Java 8 日期/时间库的性能(以及 Joda-Time 2.3 和 j.u.Calendar)。Java 8 中的新日期和时间 API