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

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

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


当前回答

共同的特征

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

b)此外:这两个库都受到Eric Evans的设计研究“TimeAndMoney”或Martin Fowler关于领域驱动风格的想法的启发,因此它们或多或少地追求流畅的编程风格(尽管并不总是完美的;-))。

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

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

性能

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

Null

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

精度

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

支持字段:

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

Enum

JSR-310提供了像DayOfWeek或Month这样的枚举,而Joda-Time没有提供这一点,因为它主要是在Java 5之前的2002-2004年开发的。

区火

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

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

理算人诉财产

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

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

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

日历系统

JSR-310提供了4个额外的日历系统。最有趣的是Umalqura(沙特阿拉伯使用)。其他3个是:民国(台湾),日本(1871年以来只有现代日历!)和泰国佛教(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在DateTimeUtils中提供了接口millisecprovider和一些辅助方法。因此,通过这种方式Joda-Time也能够支持具有不同时钟的测试驱动模型(mock等)。

持续时间的算术

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

JSR-310 => long days = chronount . days。之间(date1 date2);

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

Handling of multiple-unit-durations are also different. Even the calculation results can differ - see this closed Joda-Time issue. While JSR-310 use a very simple and limited approach to use just the classes Period (duration based on years, months and days) and Duration (based on seconds and nanoseconds), Joda-Time uses a more sophisticated way using the class PeriodType in order to control in which units a duration (Joda-Time call it "Period") shall be expressed. While the PeriodType-API is somehow awkward to use a similar way is not offered by JSR-310 at all. Especially it is not yet possible in JSR-310 to define mixed date and time durations (based on days and hours for example). So be warned if it comes to migration from one library to another. The libraries in discussion are incompatible - despite of partially same class names.

时间间隔

JSR-310不支持此特性,而Joda-Time支持有限。看看这个so -答案。

格式和解析

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

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)之间的比较。它比这篇文章更详细。

其他回答

Java 8日期/时间:

Java 8 classes are built around the human time. It makes them fast for human datetime arithmetics/conversion. Date/time component getters like getDayOfMonth have O(1) complexity in Java 8 implementation. Parsing of OffsetDateTime/OffsetTime/ZonedDateTime is very slow in Java 8 ea b121 due to exceptions thrown and caught internally in the JDK. A set of packages: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*, java.time.zone.* Instants (timestamps) Date and Time Partial Date and Time Parser and Formatter Time zones Different chronologies (calendars). Existing classes have issues like Date has no support for I18N or L10N. They are mutable! Simpler & more robust. Clocks can be injected. Clocks can be created with various properties - Static clocks, Mocked clocks, Low-precision clocks (whole seconds, whole minutes, etc). Clocks can be created with specific time zones. Clock.system(Zone.of("America/Los_Angeles")). Makes code handling date and time testable. Makes tests independent of timezone.

Joda-Time:

Joda-Time is using machine time inside. A manual implementation based on int/long values would be much faster. Joda-Time getters require the computer-to-human time calculation on every getter call, which makes Joda-Time a bottleneck in such scenarios. It is composed of immutable classes it handles Instants, Date & Time, Partials, and Durations It is flexible It is well designed. Represents dates as instants. But a date&time may correspond to more than one instant. Overlap hour when daylight savings end. As well as not have any instant that corresponds to it at all. Gap hour when daylight starts. Has to perform complex computations for simple operations. Accepts nulls as valid values on most of its methods. Leads to subtle bugs.

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

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

共同的特征

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

b)此外:这两个库都受到Eric Evans的设计研究“TimeAndMoney”或Martin Fowler关于领域驱动风格的想法的启发,因此它们或多或少地追求流畅的编程风格(尽管并不总是完美的;-))。

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

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

性能

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

Null

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

精度

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

支持字段:

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

Enum

JSR-310提供了像DayOfWeek或Month这样的枚举,而Joda-Time没有提供这一点,因为它主要是在Java 5之前的2002-2004年开发的。

区火

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

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

理算人诉财产

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

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

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

日历系统

JSR-310提供了4个额外的日历系统。最有趣的是Umalqura(沙特阿拉伯使用)。其他3个是:民国(台湾),日本(1871年以来只有现代日历!)和泰国佛教(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在DateTimeUtils中提供了接口millisecprovider和一些辅助方法。因此,通过这种方式Joda-Time也能够支持具有不同时钟的测试驱动模型(mock等)。

持续时间的算术

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

JSR-310 => long days = chronount . days。之间(date1 date2);

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

Handling of multiple-unit-durations are also different. Even the calculation results can differ - see this closed Joda-Time issue. While JSR-310 use a very simple and limited approach to use just the classes Period (duration based on years, months and days) and Duration (based on seconds and nanoseconds), Joda-Time uses a more sophisticated way using the class PeriodType in order to control in which units a duration (Joda-Time call it "Period") shall be expressed. While the PeriodType-API is somehow awkward to use a similar way is not offered by JSR-310 at all. Especially it is not yet possible in JSR-310 to define mixed date and time durations (based on days and hours for example). So be warned if it comes to migration from one library to another. The libraries in discussion are incompatible - despite of partially same class names.

时间间隔

JSR-310不支持此特性,而Joda-Time支持有限。看看这个so -答案。

格式和解析

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

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现在处于维护模式

这不是对这个问题的直接回答,但Joda-Time项目已不再处于积极的开发中。该团队建议用户迁移到更新的java。时间的API。参见Oracle教程。

来自GitHub官方项目页面:

joda时间除了保留时区外不再处于积极开发中 最新数据。从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