我知道有些问题与java.util.Date和乔达时间有关.但经过一些挖掘,我找不到java.time API(Java 8年新增,定义为JSR 310)和Joda-Time之间区别的线索.

我听说Java8是Java.time API比Joda time干净得多,可以做得更多.但我找不到比较这两者的例子.

  • java.time可以做什么是Joda-Time做不到的?
  • java能做什么.时间比乔达时间好吗?
  • 使用java.time性能更好吗?

推荐答案

Common features

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

b) 此外:这两个图书馆的灵感都来自设计研究"TimeAndMoney" from Eric EvansMartin Fowler about domain driven style的 idea ,所以他们或多或少都在争取fluent programming style(尽管并不总是完美;-).

c) 使用这两个库,我们可以得到一个真正的日历日期类型(称为LocalDate)、一个真正的墙时间类型(称为LocalTime)和构图(称为LocalDateTime).与java.util.Calendarjava.util.Date相比,这是一场非常大的胜利.

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

Performance

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

Null

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

Precision

JSR-310可以处理nanosecond个精度,而Joda Time只能处理millisecond个精度.

Supported fields:

关于Java-8(JSR-310)中支持的字段的概述由时间包中的一些类(例如ChronoFieldWeekFields)给出,而Joda-Time在这方面相当薄弱-请参见DateTimeFieldType.最缺乏Joda-Time的是这里没有本地化的周相关字段.这两个字段实现设计的一个共同特点是都基于Long类型的值(没有其他类型,甚至连枚举都没有).

Enum

JSR-310提供了enums个,比如DayOfWeekMonth,而Joda Time不提供,因为它主要是在2002-2004年Java 5之前开发的.

Zone API

a) JSR-310提供了比Joda Time更多的时区功能.后者无法通过程序访问时区偏移转换的历史,而JSR-310能够做到这一点.

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

Adjuster vs. Property

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

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

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

Calendar systems

JSR-310提供4个额外的日历系统.最有趣的是Umalqura(在沙特阿拉伯使用).另外三个是:Minguo(台湾)、日文(只有1871年以来的现代历法!)和ThaiBuddhist(只在1940年之后才正确).

Joda-Time提供基于计算基础的Islamic calendar分,而不是像乌马尔库拉那样基于视力的日历.泰式佛教也是由Joda-Time以类似的形式提供的,民国和日本的不是.除此之外,Joda-Time还提供科普特和埃塞俄比亚日历(但不支持国际化).

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

其他日历,如HebrewPersianHindu,在这两个库中都完全缺失.

Epoch days

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

Clocks

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

Duration arithmetic

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

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

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

对多个单位持续时间的处理也不同.即使是计算结果也可能不同-请看这个闭合的Joda-Time issue.虽然JSR-310使用非常简单和有限的方法只使用类Period(基于年、月和天的持续时间)和Duration(基于秒和纳秒),但是Joda-Time使用更复杂的方法使用类PeriodType来控制应该以哪些单位来表示持续时间(Joda-Time称之为"Period").虽然PeriodType-API使用起来有些笨拙,但JSR-310根本没有提供类似的方式.特别是在JSR-310中还不可能定义混合的日期和时间持续时间(例如,基于天和小时).因此,如果涉及到从一个库迁移到另一个库,请注意.讨论中的库是不兼容的-尽管类名部分相同.

Intervals

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

Formatting and Parsing

比较这两个库的最佳方法是查看相同名称的类DateTimeFormatterBuilder(JSR-310)和DateTimeFormatterBuilder(Joda Time).JSR-310-variant功能更强大一点(也可以处理任何类型的TemporalField,前提是现场实现人员已经成功地编写了一些扩展点,比如resolve()).然而,最重要的区别是——在我看来:

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

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

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

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


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

Update from 2015-06-24:

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

Java相关问答推荐

强制Mockito返回null而不是emtpy list

ittext pdf延迟签名,签名无效

多个Java线程和TreeMap.put()的非预期行为

Java List with all combinations of 8 booleans

';com.itextpdf.ext.html.WebColors已弃用

是否在允许数组元素为空时阻止 idea 为空性警告?

Chunk(Int)已弃用并标记为要删除

如何使用带有谓词参数的方法,而不使用lambda表达式

如何在 spring 数据的MongoDB派生查询方法中使用$EXISTS

我怎样才能让IntelliJ标记toString()的任何实现?

允许同时执行两个方法,但不能同时执行这两个方法

错误:未找到扩展元素在JBossEAP 7.2中安装FUSE时出错

从映射列表中检索所有键

Android Studio模拟器没有互联网

何时调用密封层次 struct 的switch 中的默认情况

我的代码是线程安全的吗?[Java、CAS、转账]

未调用OnBackPressedCallback-Activitiy立即终止

我们可以在方法中声明接口吗?

在Spring Boot中使用咖啡因进行缓存

MapStruct记录到记录的映射不起作用