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

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

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

  • 什么时候可以做Java的Joda时间不能?
  • java.time能比Joda-Time做得更好吗?
  • java.time的性能更好吗?

共同特征

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

b)另外:两个图书馆的灵感都来自Eric Evans的devise研究“TimeAndMoney”或Martin Fowler关于领域驱动风格的想法,所以他们为stream利的编程风格 (尽pipe不总是完美的;-))或多或less地努力。

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

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

性能

虽然第3点(exception捕捉)可能已经过时,请参阅@OO7的其他答案,指出对Mikhail Vorontsov的分析 – 请参阅此JDK错误 。 不同的性能(这在一般情况下有利于JSR-310 )主要是由于Joda-Time的内部实现总是使用类似机器时间的长基元(以毫秒为单位)。

空值

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

精确

JSR-310处理纳秒级精度,而Joda-Time精度达到毫秒级 。

支持的字段:

有关Java-8(JSR-310)中受支持的字段的概述由temporal-package(例如ChronoField和WeekFields )中的某些类给出,而Joda-Time在此区域相当薄弱,请参阅DateTimeFieldType 。 乔达时代最大的缺点就是缺乏本地化的周相关领域。 这两个字段实现devise的一个共同特点是都基于longtypes的值(没有其他types,甚至没有枚举)。

枚举

JSR-310提供像DayOfWeekMonth这样的枚举,而Joda-Time并没有提供这个function,因为它主要是在Java2005之前的2002 – 2004年开发的。

区域API

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

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

调节器与财产

JSR-310引入了TemporalAdjuster作为一种forms化的方式来对时间计算和操作进行外部化,特别是对于图书馆或者框架编写者来说,这是embeddedJSR-310(一种相当于静态以前的java.util.Date帮助器类)。

然而,对于大多数用户来说,这个function的价值非常有限,因为编写代码的负担仍然与用户有关。 基于新的TemporalAdjuster概念的内置解决scheme并不多,目前只有助手类TemporalAdjusters具有有限的一组操作(以及枚举Month或其他时态types)。

Joda-Time提供了一个现场软件包,但实践certificate,新的现场实现是非常难以编码的。 另一方面,Joda-Time提供了所谓的属性,这使得一些操作比JSR-310更容易和更优雅,例如property.withMaximumValue() 。

日历系统

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

Joda-Time提供了一个基于计算基础的伊斯兰教日历 ,而不是像Umalqura这样的以目击为基础的日历。 Joda-Time也以类似的forms提供泰国佛教,Minguo和日本的佛教也不是。 否则,乔达时代也提供了科普和ethiopic日历(但没有任何国际化的支持)。

欧洲人更有趣:乔达时代还提供了公历 , 朱利安和混合公历。 然而,真正的历史计算的实际价值是有限的,因为从date历史开始的不同年份的重要特征根本不被支持(同样的批评对于旧的java.util.GregorianCalendar是有效的)。

其他日历,如希伯来语或波斯或印度教在两个图书馆都完全失踪。

大纪元的日子

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

JSR-310没有接口(一个devise错误),而是一个可以用于任何时钟dependency injection的抽象类java.time.Clock 。 Joda-Time在DateTimeUtils中提供了接口MillisProvider和一些辅助方法。 所以这样Joda-Time也能够支持不同时钟的testing驱动模型(嘲讽等)。

持续时间algorithm

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

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

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

处理多个单位时间也是不同的。 即使计算结果可能会有所不同 – 请参阅此封闭的Joda-Time问题 。 尽pipeJSR-310使用非常简单而有限的方法来使用类Period (基于年,月,日的Duration )和Duration (基于秒和纳秒),Joda-Time使用更复杂的方式使用PeriodType为了控制在哪个单位中持续时间(Joda-Time称之为“期间”)。 虽然PeriodType -API不知何故使用类似的方式是完全不提供JSR-310的。 特别是在JSR-310中,还不可能定义混合的date和时间(例如基于date和小时数)。 所以如果涉及到从一个图书馆到另一个图书馆的迁移,就要警惕了 讨论中的图书馆是不相容的 – 尽pipe部分名称相同。

间隔

JSR-310不支持此function,而Joda-Time支持有限。 另见这个SO-answer 。

格式化和分析

比较两个库的最好方法是查看同名类DateTimeFormatterBuilder (JSR-310)和DateTimeFormatterBuilder (Joda-Time)。 JSR-310变体稍微强大一点(也可以处理任何types的TemporalField只要字段实现者已经设法编译一些像resolve()这样的扩展点)。 然而,最重要的区别是 – 在我看来:

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

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

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

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


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

2015-06-24更新:

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

Java 8date/时间:

  1. Java 8类是围绕着人类的时间而build立的。 这使得他们快速的人类date时间算术/转换。
  2. date/时间组件getter(如getDayOfMonth )在Java 8实现中具有O(1)复杂性。
  3. 在Java 8 ea b121中parsingOffsetDateTime / OffsetTime / ZonedDateTime的速度非常缓慢, ZonedDateTime是由于在JDK内部抛出和捕获到exception。
  4. 一组包: java.time.*java.time.chrono.*java.time.format.*java.time.temporal.*java.time.zone.*
  5. 时间戳(时间戳)date和时间部分date和时间分析器和格式化器时区不同的年表(日历)。
  6. 现有的类有问题像date不支持I18N或L10N。 他们是可变的!
  7. 更简单,更健壮。
  8. 时钟可以被注入。
  9. 时钟可以创build各种属性 – 静态时钟,模拟时钟,低精度时钟(整秒,整分钟等)。
  10. 时钟可以用特定的时区创build。 Clock.system(Zone.of("America/Los_Angeles"))
  11. 使代码处理date和时间可testing。
  12. 使testing独立于时区。

乔达时间:

  1. Joda-Time正在使用机器时间。 基于int / long值的手动实现会更快。
  2. 乔达时间的获得者需要计算每个获得者的时间计算,这使得乔达时间成为这种情况下的一个瓶颈。
  3. 它由不可变类组成,它处理Instants,Date&Time,Partial和Durations。它是灵活的它devise的很好。
  4. 代表date即时。 但date和时间可能对应于多个瞬间。 夏令时结束时重叠小时。 以及没有任何对应于它的瞬间。 白天开始的时间间隔。 必须对简单的操作执行复杂的计算。
  5. 接受空值作为其大部分方法的有效值。 导致微妙的错误。

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

Java 8date/时间库性能(以及Joda-Time 2.3和juCalendar) 。 Java中的新date和时间API