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

时间:2014-07-08 12:28:58

标签: java datetime java-8 jodatime java-time

我知道有关于java.util.Date和Joda-Time的问题。但经过一番挖掘后,我无法找到关于java.time APIJava 8中新增的,JSR 310)和Joda-Time之间差异的线索。

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

  • Joda-Time不能做什么java.time?
  • java.time能比Joda-Time做得更好吗?
  • java.time的性能是否更好?

4 个答案:

答案 0 :(得分:391)

常用功能

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

b)此外:两个图书馆都受到设计研究"TimeAndMoney" from Eric Evans的启发或来自Martin Fowler about domain driven style的想法,所以他们或多或少地为fluent programming style而努力(尽管并不总是完美的;-))

c)对于这两个库,我们得到一个真实的日历日期类型(称为LocalDate),一个真实的墙上时间类型(称为LocalTime)和组合(称为LocalDateTime)。与旧java.util.Calendarjava.util.Date相比,这是一个非常大的胜利。

d)两个图书馆都使用以方法为中心的方法,这意味着他们鼓励用户使用getDayOfYear()代替get(DAY_OF_YEAR)。与java.util.Calendar相比,这会产生许多额外的方法(尽管后者由于过度使用整数而根本不是类型安全的。)

<强>性能

请参阅@ OO7的另一个答案指向Mikhail Vorontsov的分析,尽管第3点(异常捕获)可能已经过时 - 请参阅this JDK-bug。不同的性能(通常支持JSR-310)主要是因为Joda-Time的内部实现总是使用类似机器时间的长基元(以毫秒为单位)。

<强>空

Joda-Time经常使用NULL作为系统时区,默认语言环境,当前时间戳等的默认值,而JSR-310几乎总是拒绝NULL值。

<强>精密

JSR-310处理nanosecond精度,而Joda-Time的精度限制为millisecond

支持的字段:

有关Java-8(JSR-310)中受支持字段的概述由temporal-package中的某些类(例如ChronoFieldWeekFields)给出,而Joda-Time则相当弱这个区域 - 见DateTimeFieldType。 Joda-Time最缺乏的是缺乏本地化的周相关领域。两个字段实现设计的一个共同特点是两者都基于long类型的值(没有其他类型,甚至没有枚举)。

<强>枚举

JSR-310提供enums DayOfWeekMonth,而Joda-Time则不提供此功能,因为它主要是在Java 5之前的2002-2004年开发的。< / p>

专区API

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

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

调整员与财产

JSR-310引入了TemporalAdjuster - 接口作为外化时间计算和操作的形式化方法,特别是对于库或框架编写者来说,这是嵌入JSR-310新扩展的一种很好且相对简单的方法(一种等同于前java.util.Date的静态助手类。)

但对于大多数用户而言,此功能的价值非常有限,因为编写代码的负担仍然是用户的负担。基于新TemporalAdjuster概念的内置解决方案并不多,目前只有辅助类TemporalAdjusters具有有限的操作集(以及枚举Month或其他时间类型)。

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

日历系统

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

Joda-Time基于计算基础提供Islamic calendar - 而不是像Umalqura那样的基于目击的日历。 Joda-Time也以类似的形式提供泰国佛教徒,Minguo和日本人没有。否则Joda-Time也提供科普特和ethiopic日历(但没有任何国际化支持)。

欧洲人更感兴趣:Joda-Time还提供GregorianJulian和混合格里高利 - 朱利安日历。然而,实际历史计算的实际价值是有限的,因为根本不支持日期历史中不同年份开始的重要特征(同样的批评对旧java.util.GregorianCalendar有效。)

两个图书馆完全缺少HebrewPersianHindu等其他日历。

大纪元

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

<强>时钟

JSR-310没有接口(设计错误),但是抽象类java.time.Clock可以用于任何时钟依赖注入。 Joda-Time提供了接口MillisProviderDateTimeUtils中的一些辅助方法。所以这样Joda-Time也能够支持具有不同时钟的测试驱动模型(模拟等)。

持续时间算术

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

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

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

多单位持续时间的处理也不同。即使计算结果也可能不同 - 请参见此结束Joda-Time issue。虽然JSR-310使用非常简单且有限的方法仅使用类Period(基于年,月和日的持续时间)和Duration(基于秒和纳秒),Joda-Time使用使用类PeriodType的更复杂的方式是为了控制在哪个单元中表达持续时间(Joda-Time称之为&#34; Period&#34;)。虽然PeriodType - API在某种程度上难以使用,但JSR-310根本不提供类似的方法。特别是在JSR-310中还不能定义混合日期和持续时间(例如,基于天和小时)。因此,如果涉及从一个库迁移到另一个库,请注意。讨论中的库是不兼容的 - 尽管类名相同。

<强>间隔

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

格式化和解析

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

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

JSR-310的另一个优点是支持独立的月份名称,这在俄语或波兰语等语言中很重要.Joda-Time有no access to such resources - 甚至不在Java-8平台上。

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

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


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

从2015-06-24更新:

与此同时,我已经找到了为Java中的不同时间库编写和publish a tabular overview的时间。这些表还包含Joda-Time v2.8.1和Java-8(JSR-310)之间的比较。它比这篇文章更详细。

答案 1 :(得分:39)

Java 8日期/时间:

  1. Java 8类是围绕人类时间构建的。这使得它们可以快速进行人类日期算术/转换。
  2. getDayOfMonth这样的日期/时间组件getter在Java 8实现中具有O(1)复杂性。
  3. 在Java 8 ea b121中解析OffsetDateTime / OffsetTime / ZonedDateTime非常慢,因为在JDK内部抛出并捕获了异常。
  4. 一组包:java.time.*java.time.chrono.*java.time.format.*java.time.temporal.*java.time.zone.*
  5. Instants(timestamps)日期和时间Partial Date和Time Parser和Formatter时区不同的年表(日历)。
  6. 现有类存在类似Date不支持I18N或L10N的问题。它们是可变的!
  7. 更简单&amp;更健壮。
  8. 可以注入时钟。
  9. 可以创建具有各种属性的时钟 - 静态时钟,模拟时钟,低精度时钟(整秒,整分钟等)。
  10. 可以使用特定时区创建时钟。 Clock.system(Zone.of("America/Los_Angeles"))
  11. 使代码处理日期和时间可测试。
  12. 使测试独立于时区。
  13. Joda-Time:

    1. Joda-Time正在使用机器时间。基于int / long值的手动实现会快得多。
    2. Joda-Time getters需要在每次getter调用时进行计算机到人的时间计算,这使得Joda-Time成为这种情况下的瓶颈。
    3. 它由不可变的类组成,它处理Instants,Date&amp;时间,部分和持续时间它很灵活它设计得很好。
    4. 将日期表示为瞬间。但是日期和时间可能对应于不止一个瞬间。夏令时结束时的重叠时间。并且根本没有任何对应的瞬间。白天开始时的间隙时间。必须为简单的操作执行复杂的计算。
    5. 在大多数方法上接受空值作为有效值。导致微妙的错误。
    6. 有关详细比较,请参阅:

      Java 8 Date/Time library performance (as well as Joda-Time 2.3 and j.u.Calendar)。 &安培; New Date & Time API in Java 8

答案 2 :(得分:3)

Joda-Time现在处于维护模式

这不是问题的直接答案,但是Joda-Time项目不再处于积极开发中。该小组建议用户迁移到更新的 java.time API。参见tutorial by Oracle

GitHub项目官方页面上:

除了保持时区,Joda-time不再处于活跃状态 最新数据。从Java SE 8开始,要求用户迁移到 java.time(JSR-310)-JDK的核心部分取代了 项目。对于Android用户,在API 26+中添加了java.time。专案 需要支持较低的API级别的用户可以使用ThreeTenABP库。

答案 3 :(得分:0)

<块引用>

该项目由 Joda-Time (Stephen Colebourne) 的作者和 Oracle 联合领导,在 JSR 310 下,并将出现在新的 Java SE 8 包 java.time 中。

https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html