The Joda-Time 2.4 date and time Java library has been released. It's the first Joda-Time release for 2014, and it contains enhancements, bug fixes and a time zone update. No deprecations have been introduced. Joda-Time 2.4 is released under the Apache License Version 2 and requires JDK 5+.
Here are the enhancements in Joda-Time 2.4.
- The methods Duration.multipliedBy(long multiplicand), Duration.dividedBy(long divisor), and Duration.negated() have been added to the public interface.
- In LocalDate.hashCode(), the unnecessary volatile modifier on the cached hashCode (int iHash) has been removed. The cached hashCode now follows the racy single-check idiom.
- The DateTimeParserBucket internals have been changed to use CharSequence without affecting the public API. This allows DateTimeParserBucket to be re-used on a single thread and lessen short lived object creation. CharSequence can also be used in parsing, but only by creating a mutable DateTimeParserBucket. These are low-level constructs for advanced use cases. See issue #111 for more information.
- Support for java.lang.Appendable has been added to DateTimeFormat, DateTimeFormatter, DateTimePrinter. StringBuilder is also used internally instead of StringBuffer.
- Improved the performance of chronology lookup in the classes under the joda.time.chrono package. It now uses ConcurrentHashMap instead of synchronized Maps. The cache lookup of GJChronologies was also simplified.
- Improved the performance of DateTimeFormat pattern cache lookups by using AtomicReferenceArray.
- Simplified and increased the performance the GJLocaleSymbols symbols lookup.
- DateTimeZone data has been updated to version 2014e.
Here are the bug fixes in Joda-Time 2.4.
- Fixed incorrect handling of centuries and eras in DateTimeField.getDurationField() and DateTimeField.getRangeDurationField().
- Fixed DateTimeZone.getOffsetFromLocal() to correctly handle the last cutover in DST history. This is a conversion issue from Local to UTC.
- During Period creation, if one end is within a DST overlap and one beyond the overlap, the Period was incorrect. The calculation has been fixed and the extra hour is no longer added.
- DateTimeUtils.isContiguous(ReadablePartial) method could throw a NullPointerException when evaluating weird partials.
- Fixed UnsupportedOperationException in Period.normalizedStandard(PeriodType) when PeriodType is missing either years or months.
- Added missing validation in Partial.with(DateTimeFieldType,int) to prevent invalid partials to created.
- Adding zero to a MutableDateTime no longer changes the offset during DST overlap in autumn.
- Added validation in DateTime/MutableDateTime constructors that takes milliseconds. new DateTime(Long.MAX_VALUE) is no longer valid and is rejected.
- Day-of-month and day-of-year fields now returns the correct result for isLeap().
- Insist that year > weekyear when creating Partials to allow for comparisons.
- Handle weird TimeZone implementations with null ID. Calling DateTimeZone.forTimeZone() throws a NullPointerException when passed a null ID.
- Some Android implementations throw ClassCastException when comparing different types. This fix handles broken Android implementations better.
- Better concurrency in DateTimeFormatterBuilder parsing using ConcurrentHashMap.
- DateTimeZone was incorrectly calling ThreadGroup.uncaughtException() and has been changed to throw an RuntimeException instead.