Java 8 Date Time API (Java . Time)与Joda-Time的区别

我知道有关于java.util.Date和Joda-Time的问题。但经过一番挖掘,我找不到关于java。时间的API(在Java 8中新增,由JSR 310定义)和Joda-Time之间差异的线程。

我听说Java 8是Java。time API比Joda-Time更干净,可以做更多的事情。但我找不到比较这两者的例子。

  • 什么可以java。时间做不到的事,时间做不到?
  • 什么可以java。时间胜过joda时间?
  • java.time的性能更好吗?
91592 次浏览

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. 即时(时间戳)日期和时间部分日期和时间解析器和格式化器时区不同的年表(日历)。
  6. 现有类存在Date不支持I18N或L10N等问题。它们是可变的!
  7. 简单的,更健壮。
  8. 时钟可以被注入。
  9. 时钟可以创建各种属性-静态时钟,模拟时钟,低精度时钟(整个秒,整个分钟等)。
  10. 可以使用特定的时区创建时钟。Clock.system(Zone.of("America/Los_Angeles"))
  11. 使代码处理日期和时间可测试。
  12. 使测试独立于时区。

Joda-Time:

  1. Joda-Time在里面使用机器时间。基于int/long值的手动实现要快得多。
  2. Joda-Time getter需要对每个getter调用进行计算机到人的时间计算,这使得Joda-Time成为此类场景中的瓶颈。
  3. 它由不可变类组成,它处理即时、日期和amp;时间,部分和持续时间它是灵活的它是精心设计的。
  4. 将日期表示为瞬间。但是一个日期时间可以对应多个瞬间。夏令时结束时重叠时间。同时也没有任何与之对应的瞬间。白天开始的空档时间。必须为简单的操作执行复杂的计算。
  5. 在大多数方法上接受null作为有效值。导致微妙的错误。

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

< p > Java 8日期/时间库性能(以及Joda-Time 2.3和j.u.d alcalendar)。, 新日期Java 8中的时间API < / p >

共同的特征

a)两个库都使用不可变类型。Joda-Time还提供了额外的可变类型,如MutableDateTime

b)此外:两个库都受到设计研究埃里克·埃文斯的《时间和金钱》或来自Martin Fowler关于领域驱动的风格的想法的启发,所以它们或多或少地努力实现流畅的编程风格(尽管并不总是完美;-))。

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

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

性能

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

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

精度

JSR-310处理纳秒精度,而Joda-Time仅限于毫秒精度。

支持字段:

关于Java-8 (JSR-310)中支持的字段的概述是由temporal包中的一些类给出的(例如ChronoFieldWeekFields),而Joda-Time在这方面相当弱——参见DateTimeFieldType。Joda-Time最大的不足是缺少与周相关的局部字段。这两种字段实现设计的一个共同特征是它们都基于long类型的值(没有其他类型,甚至不是enum类型)。

枚举

JSR-310提供枚举,如DayOfWeekMonth,而Joda-Time不提供这一点,因为它主要是在Java 5之前的2002-2004年开发的。

区API

a) JSR-310提供了比Joda-Time更多的时区特性。后者不能产生对时区偏移转换历史的编程访问,而JSR-310能够做到这一点。

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

理算人诉财产

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

然而,对于大多数用户来说,这个特性的价值非常有限,因为编写代码的负担仍然在用户身上。基于新的__abc0概念的内置解决方案并不多,目前只有辅助类TemporalAdjusters具有有限的操作集(以及枚举Month或其他时态类型)。

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

日历系统

JSR-310提供了4个额外的日历系统。最有趣的是Umalqura(在沙特阿拉伯使用)。另外3个是:民国(台湾),日本(1871年以后只有现代日历!)和ThaiBuddhist(1940年以后才正确)。

Joda-Time提供了一个基于计算基础的伊斯兰日历 -而不是像Umalqura那样基于视觉的日历。泰国佛教也提供了类似的形式,民国和日本的一个没有。此外,Joda-Time也提供科普特和埃塞俄比亚日历(但不支持国际化)。

对欧洲人来说更有趣的是:Joda-Time还提供格雷戈里朱利安和混合公历-儒略历。然而,对于真正的历史计算的实用价值是有限的,因为重要的功能,如不同的年份开始的日期历史根本不支持(同样的批评适用于旧的java.util.GregorianCalendar)。

其他日历,如希伯来语波斯印度教,在这两个库中都完全缺失。

时代天

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

时钟

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

持续时间的算术

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

jsr - 310 =比;long days = ChronoUnit.DAYS.between(date1, date2);

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

多单元持续时间的处理也有所不同。甚至计算结果也可能不同-请参阅这个封闭的Joda-Time问题。虽然JSR-310使用了非常简单和有限的方法,只使用类Period(基于年、月和日的持续时间)和Duration(基于秒和纳秒的持续时间),但Joda-Time使用了更复杂的方法,使用类PeriodType来控制持续时间的单位(Joda-Time称其为“周期”)应该表示。虽然使用类似的方式PeriodType-API有些尴尬,但JSR-310根本没有提供。特别是在JSR-310中还不可能定义混合的日期和时间持续时间(例如基于天和小时)。因此,如果要从一个库迁移到另一个库,请注意。讨论中的库是不兼容的——尽管类名部分相同。

时间间隔

JSR-310不支持此特性,而Joda-Time支持有限。另请参阅所以答案

格式和解析

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

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

JSR-310的另一个优点是支持独立的月份名称,这在俄语或波兰语等语言中很重要。Joda-Time有不能访问这些资源 -甚至在Java-8平台上都没有。

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

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


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

更新日期2015-06-24:

与此同时,我已经找到时间在Java中为不同的时间库编写和发布一个表格式概述。这些表还包含Joda-Time v2.8.1和Java-8 (JSR-310)之间的比较。它比这篇文章更详细。

Joda-Time现在处于维护模式

这不是对问题的直接回答,但< em > Joda-Time < / em >项目已不再处于积极的开发中。该团队建议用户迁移到更新的java.time API。看到Oracle教程

来自官方GitHub项目页面:

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

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

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