In continuation with our discussion about JSR 310 (the New Java Date and Time API), we will now move further to understand the JODA time API in brief and then we will have a detailed overview of JSR 310. If you have not read the first part of this discussion, please go and check out Part 1 : Overview of existing Date and Time API
Till now, we have seen that Java’s existing Date and Time API has lot of issues and shortcomings. This has helped Joda Time API to gain popularity in the Java developers. Joda Time API is a set of API that addresses most of the shortcomings of the Java’s own Date and Time API.
The Joda Time API, drastically changes the Date and Time handling in java with the help its uniform structure. The Joda Time API supports eight different Calendars like Gregorian, Julian, Buddhist, Islamic etc. This API is really famous not only because of the weaknesses of Java Date and Time API but also because of its easy to use, extensible and simplified design. This API has set of various Date and Time classes which are immutable by nature and can be used safely within multithreaded environments. Lets have a quick overview of the key concepts of Joda Time API
As per the Joda Time documentation the instant can be defined as below.
An Instant is a moment in date-time continuum specified as a number of milliseconds from the start of 1970-01-01.
The Instant is represented in the form of an interface ReadableInstant and implemented by the mostly used class DateTime. This implementation is immutable and hence thread safe. The fields on this class instance can’t be changed once it is created. The API also has MutableDateTime – a mutable implementation of ReadableInstant.
The other major implementation of the ReadableInstant are Instant and DateMidnight.
The Instant represents exact point in a time line irrespective of Chronology or Time Zone in the form of milliseconds.The DateMidnight represents a date whose time component is set at Midnight (start of the date). This class instance is a representation of midnight in the form of milliseconds and doesn’t represent the whole day.
As the name suggests the it represents interval of time from once instant to the other instant where the start instant is inclusive and the end instant is exclusive, the end instant is always greater than the start instant, and both of the instants belong to the same Chronology and Time zone.
The interval in Joda time is represented in the form of an interface ReadableInterval along with a Interval (immutable interval) and MutableInterval implementations.
This is a duration of time measured in milliseconds. This doesn’t have any restrictions of Chronology or Time zone and it is just represents the time duration between two instants. It is also used to compare two intervals. Intervals give us duration and durations can be compared to each other.
In the API duration is represented in an interface ReadableDuration. the Duration implementation is also available in mutable and immutable versions. Duration doesn’t contain fields like day or seconds, but it can be converted to Period to obtain the fields.
It is a time Period defined in terms of fields like year, month, week, day, hour etc. This is really useful feature as it gives us flexibility to divide things into year, months, days etc. When we say add a period of 1 month to 1st April and the answer will be 1 May (added 30 days) the same thing when tried with 1st May the answer will be 1 June (added 31 days). As a programmer we don’t need to bother about such things as long as the Chronology and the Time Zone is correct. Adding 1 Day when DST changes may correctly add only 23 hours but if we added 24 hours explicitly the results will be wrong.
Similar to other features the Period is also represented in the form of an interface ReadablePeriod and is available in mutable and immutable implementations.
This is the most important part of the Joda time system as it handles the complex rules for a Calendar. Many different Chronologies are supported by the means of subclassing e.g. ISO, Gregorian, Coptic etc. To setup any Chronology, we should use factory methods provided on each subclasses.
All of the specific Chronology implementations are immutable and thread safe. This class is really great on the design side but a kind of overhead. That is mainly because, for most of the times users will be interested in using the ISO chronology but the Chronology and field classes are maintained as Singletons and there will there will be a cost of creation and garbage collection.
in the Joda Time API the time zone is represented as DateTimezone. Time zone has a set of rules that converts a time of one geographical location to the other. Usually all of the time zones are represented relative to Greenwich Mean Time (GMT), but the Joda Time library refers to the Universal Coordinated Time (UTC).
The DateTimeZone class has factory methods to create a specific TimeZone instance.
DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
It is also capable of giving a DateTimeZone based on the offset hours.
DateTimeZone tz = DateTimeZone.forOffsetHours(offset_hours);
Similar to Java Date and Time API, the Joda Time API also supports a default time zone that is when the time zone is not specified. API also has a method to set a default time zone.
DateTimeZone tz = DateTimeZone.getDefault(); DateTimeZone.setDefault(default_time_zone);
Just like the many of the Joda Time classes the DateTimeZone is also immutable and hence thread safe.
The Joda Time API addresses most of the drawbacks of the existing Java Date and Time API, and it is the best and the most powerful Date and Time library available as of the now. But the Joda time API also has few design flaws.
In the Object Oriented paradigm the interfaces play a vital role in providing flexibly and reusability. Mostly we create a reference of the class Type and make is refer to instance of a specific implementation. So that we can anytime change the implementation instance while keeping the code same.
In Joda Time API this flexibility is lacking. For an example, have a look at ReadableInstant interface. This interface has implementations like Instant and MutableInstant and hence this interface cannot contain the setters implemented by MutableInstant.
We cannot have ReadableInstant reference along with MutableInstant instance and utilise it’s mutability. We have to use the reference of a concrete type MutableInstant. Joda Time documentation encourages developers to use concrete references and Type references.
The API still manage to provide some sort of implementation flexibility by providing conversion methods as shown below.
DateTime dateTime = dateTimeInterfaceReference.toDateTime();
This can be used inside methods where the method accepts a parameter of an interface type and the method converts it to the desired implementation.
The the Joda Time library the handling of nulls is not uniform throughout the API and most of the methods accepts it as a valid value. The date time classes when set to null represents the epoch time (i.e. 1970-01-01T00:00Z) while the duration or period considers null as zero.
This may cause number of issues when a program accidentally and unexpectedly sets null. As the API doesn’t throw exception for the null values system may produce unexpected outputs and that is hard to debug.
One of the major design strength of the Joda Time API is its pluggable Chronology. No doubts this pluggability gives lot of flexibility and reusability but it can result into serious issues.
Suppose you call getMonthOfDay method on the Joda Time and what if it returns 13. December is still the 13th month and January is still the 1st. This can happen if the Chronology is set for Coptic Chronology which has 13 months in a year. You have no clue, before calling the method, to know the Chronology the instance is set for. Hence it would have been better if they had not supported pluggable Chronology.
The Joda Time API is also has architectural complexities and even smaller functional changes results in big design changes. The major issues are with pluggable chronologies, improper differentiation of machine and the human aspects of the timeline and the complexity of DST overlap behaviours.
There was a thought of including the Joda Time API as a part of JDK, but because of the design flaws in the system, the author decided to develop a completely new API from scratch and include it in JDK. This API is known as JSR 310 (new Java Date and Time API).
In this part we have gone through the brief of the famous Joda Time API and tried to understood the cons. In the next section we will touch the JSR 310 (new Java Date and Time API) in detail with the help of examples.