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

标签 java datetime java-8 jodatime java-time

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

我听说 Java 8 的 java.time API 更简洁,而且比 Joda-Time 能做的更多。但我找不到比较两者的例子。

  • java.time 能做什么而 Joda-Time 不能?
  • java.time 有什么比 Joda-Time 更好的地方?
  • java.time 的性能更好吗?
  • 最佳答案

    共同特点

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

    b) 此外:两个图书馆的灵感都来自设计研究 "TimeAndMoney" from Eric Evans或来自 Martin Fowler about domain driven style 的想法所以他们或多或少都在为 fluent programming style 而奋斗(虽然并不总是完美的;-))。

    c) 通过这两个库,我们得到了一个真实的日历日期类型(称为 LocalDate )、一个真实的挂墙时间类型(称为 LocalTime )和组合(称为 LocalDateTime )。与旧的 java.util.Calendar 相比,这是一个非常大的胜利和 java.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精度。

    支持的字段:

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

    枚举

    JSR-310 提供 enums喜欢 DayOfWeekMonth而 Joda-Time 没有提供这个,因为它主要是在 2002-2004 年之前开发的 Java 5 .

    区域API

    a) JSR-310 提供了比 Joda-Time 更多的时区特性。后者无法以编程方式访问时区偏移转换的历史记录,而 JSR-310 能够做到这一点。

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

    调节器与属性(property)

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

    然而,对于大多数用户来说,这个特性的值(value)非常有限,因为编写代码的负担仍然在用户身上。基于新的内置解决方案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 也以类似的形式提供 Thai-Buddhist,Minguo 和 Japan 不提供。否则 Joda-Time 也提供科普特和埃塞俄比亚日历(但不支持任何国际化)。

    欧洲人更有趣:Joda-Time 还提供 Gregorian , Julian和混合公历-儒略历。然而,真实历史计算的实用值(value)是有限的,因为根本不支持日期历史中不同年份开始的重要特征(同样的批评对旧的 java.util.GregorianCalendar 有效)。

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

    大纪元

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

    钟表

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

    持续时间算术

    两个库都支持以一个或多个时间单位计算时间距离。但是,在处理单单元持续时间时,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 中还不可能定义混合的日期和时间持续时间(例如基于天和小时)。因此,如果涉及从一个库迁移到另一个库,请注意。讨论中的库是不兼容的——尽管类名部分相同。

    间隔

    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)和更多字段。

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

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

    2015-06-24 更新:

    同时我已经找到时间写和publish a tabular overview用于 Java 中的不同时间库。这些表还包含 Joda-Time v2.8.1 和 Java-8 (JSR-310) 之间的比较。比这个帖子详细。

    关于java - Java 8 日期时间 API (java.time) 和 Joda-Time 之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24631909/

    相关文章:

    MySQL 查询 - 最近的月份/年份

    linux - Perl DateTime::Locale::en 错误

    java - 如何使用 Jackson 库获取 JSON 响应的嵌套属性?

    java - 如何使用 JPA 和 Spring 在列表中查找具有字段的不同行?

    java - log4j日志问题

    java - wicket7 中未填充数据 View

    javax.validation 2.0.1 List<Object> 在 spring boot 中不起作用

    java - ASCII 中的六个不同的 '?' 字符?

    python - 在 python 中指定时区感知时间

    lambda - 使用 flatMap 将三重列表转换为双重列表