我知道有关于java.util.Date和Joda-Time的问题,但是经过一番搜索,我没有找到关于Java 8引入的java.time API(由JSR 310定义)和Joda-Time之间差异的讨论。
我听说Java 8的java.time API更加简洁,而且可以做更多的事情,但我找不到比较两者的例子。
- java.time能做什么Joda-Time不能做的?
- java.time比Joda-Time做得更好的是什么?
- java.time的性能是否更好?
我知道有关于java.util.Date和Joda-Time的问题,但是经过一番搜索,我没有找到关于Java 8引入的java.time API(由JSR 310定义)和Joda-Time之间差异的讨论。
我听说Java 8的java.time API更加简洁,而且可以做更多的事情,但我找不到比较两者的例子。
常见特点
a)两个库都使用不可变类型。Joda-Time还提供了额外的可变类型,如MutableDateTime
。
b)此外:这两个库都受到设计研究"时间和金钱" from Eric Evans或Martin Fowler有关领域驱动样式的思想的启发,因此它们更多或少地追求一种流畅的编程风格(虽然不总是完美的;-))。
c)使用这两个库,我们可以获得真正的日历日期类型(称为LocalDate
)、真正的墙壁时间类型(称为LocalTime
)以及组合(称为LocalDateTime
)。与旧的java.util.Calendar
和java.util.Date
相比,这是一个非常大的优势。
getDayOfYear()
而不是get(DAY_OF_YEAR)
。与java.util.Calendar
相比,这会导致许多额外的方法(尽管后者由于过度使用int而根本不安全)。
性能
请参见@OO7的另一个答案,指向Mikhail Vorontsov的分析,尽管第3点(异常捕获)可能已经过时-请参见this JDK-bug。不同的性能(通常有利于JSR-310)主要是因为Joda-Time的内部实现始终使用类似机器时间的长整型(以毫秒为单位)。
空值
Joda-Time经常将NULL用作系统时区、默认语言环境、当前时间戳等的默认值,而JSR-310几乎总是拒绝NULL值。
精度
JSR-310处理纳秒精度,而Joda-Time仅支持毫秒精度。
支持的字段:
Java-8(JSR-310)中的一些类(例如ChronoField和WeekFields)提供了有关支持字段的概述,而Joda-Time在此领域相对较弱 - 请参见DateTimeFieldType。 Joda-Time最大的缺点是缺少本地化的周相关字段。这两种字段实现设计的共同特点是都基于长整型值(没有其他类型,甚至没有枚举类型)。
枚举
JSR-310提供了枚举,例如DayOfWeek
或Month
,而Joda-Time没有这样做,因为它主要是在2002年至2004年之间开发的,早于Java 5。
时区API
a) JSR-310比Joda-Time提供更多的时区特性。后者无法以编程方式访问时区偏移转换的历史记录,而JSR-310可以做到这一点。
b) 提醒您:JSR-310已将其内部时区存储库移动到新位置并使用不同格式。旧的库文件夹lib/zi不再存在。
调整器与属性
JSR-310引入了TemporalAdjuster接口作为一种规范化的方式来外部化时间计算和操作,特别是对于库或框架编写者,这是一种很好而相对简单的方式来嵌入JSR-310的新扩展(一种类似于以前java.util.Date的静态帮助类的等价物)。java.util.GregorianCalendar
),因此其实用价值有限。时钟
JSR-310没有接口(这是一个设计错误),但有一个抽象类java.time.Clock
,可用于任何时钟依赖注入。相反,Joda-Time提供了接口MillisProvider和一些辅助方法DateTimeUtils。因此,Joda-Time也能够支持使用不同时钟(模拟等)的测试驱动模型。
持续时间算术
两个库都支持在一个或多个时间单位中计算时间间隔。然而,当处理单单位持续时间时,JSR-310风格显然更好(并且基于long而不是int):
JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);
Joda-Time => int days = DAYS.daysBetween(date1, date2).getDays();
Period
(基于年、月和日的持续时间)和Duration
(基于秒和纳秒),但Joda-Time使用了一种更复杂的方式,使用PeriodType
类来控制一个持续时间(Joda-Time称其为“Period”)应该表示为哪些单位。虽然PeriodType
-API的使用方式有些笨拙,但JSR-310根本没有提供类似的方式。尤其是在JSR-310中尚不可能定义混合日期和时间持续时间(例如基于天和小时)。因此,在从一个库迁移到另一个库时要小心。尽管部分类名相同,但讨论中的库是不兼容的。JSR-310不支持此功能,而Joda-Time有限的支持。另请参阅SO-answer。
格式化和解析
比较这两个库的最佳方法是查看同名类DateTimeFormatterBuilder(JSR-310)和DateTimeFormatterBuilder(Joda-Time)。 JSR-310变体稍微更强大(还可以处理任何类型的TemporalField
,只要字段实现者成功编写了一些扩展点,例如resolve())。然而,最重要的区别在于 - 我认为:
java.time.Duration
的开始或结束,与以时间轴为锚点的间隔相反。这种 JSR-310 类型只是自未知起始时间以来经过的秒数和纳秒数的一对。 - Meno HochschildJoda-Time:
有关更详细的比较,请参见:
Java 8日期/时间库性能(以及Joda-Time 2.3和j.u.Calendar)。 & Java 8中的新日期和时间API
https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html