Differences between Date, DateTime and Calendar in Java 7
I am using Java 7 to develop an application for scheduling conferences.
I have seen that there are several data types to handle dates.
Example:
private Date creationDate;
private DateTime creationDate;
private Calendar creationDate;
My question is: What is the difference between the type Calendar
, Date
and DateTime
?
2 answers
From the documentation of java.util.Date
(translated):
The Class
Date
represents a specific instant in time, with millisecond accuracy.
While java.util.Calendar
(translated, emphasis mine):
The
Calendar
class is a abstract class that provides methods for converting between a specific instant in time and a set of calendar fields such as YEAR, MONTH, DAY_OF_MONTH), HOUR and so, and to manipulate the calendar fields, such as getting next week's date.
The biggest problem here in class design Date
is that it is mutable, when it should be immutable and the operation on dates like increase (or decrease) days, hours, seconds, years, etc, and generation of Date
s should be through Calendar
. At least this is the way I usually work to avoid problems when handling data from Date
. In Java 8 this is solved by implementing a new internal framework for date and time handling called Java 8 Date and time and classes can be found under Package java.time
(your question is based on Java 7, so I just mention this part of Java 8, I won't delve further at this point).
To use Calendar
, I always recommend initializing it as follows:
Calendar calendar = Calendar.getInstance();
Since there is more than one implementation of Calendar
, being the best known (and used) GregorianCalendar
, but they are also BuddhistCalendar
and JapaneseImperialCalendar
(at least from the Open JDK code). The Calendar#getInstance
method delegates the creation of the calendar to the createCalendar
method which for Java 8 is implemented as follows (reviewing hotspot source code):
private static Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
}
Calendar cal = null;
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
if (cal == null) {
// If no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}
I always recommend working with Calendar
because it is considered good practice to work with abstract classes and interfaces as much as possible because of working with the implementation directly. This is covered here (in English): https://stackoverflow.com/q/383947/1065197
I don't know of any DateTime
class declared in JDK 7. Perhaps you are referring to the class org.joda.time.DateTime
of the library Joda Time (curious name in Spanish), which arises as a solution to avoid working with Date
that is mutable. DateTime
is immutable and operations you perform on a DateTime
will actually create a new instance of DateTime
instead of modifying the instance current.
If you want to know which class you should use in your projects, I would give you the following recommendations:
- for your entities, declare fields of type
Date
(make sure they are from packagejava.util
). - to perform operations on
Date
such as adding or removing time, there are 2 options:- creates an object of type
Calendar
, sets its time from an instance ofDate
viaCalendar#setTime
, performs the necessary operations, and gets theDate
fromCalendar
viaCalendar#getTime
. - procedure similar to the one described above, but using Joda's
DateTime
.
- creates an object of type
- if you want to represent a date and time in a textual way, I recommend using
SimpleDateFormat#format(Date)
(eye, getDate
and notCalendar
) and avoid usingDate#getXyz
methods. You could also useCalendar#get(Calendar.<campo>)
but the code would be very verbose (I don't know a translation of this).
Why not directly declare the use of DateTime
in the fields of your entities? Because there are frameworks that do not support direct conversion unless you implement particular converters for it. Some examples: Hibernate1, JSF, Spring, etc.
1 Hibernate 5 now offers support for Java 8's Date time library. I guess the frameworks will gradually go down that path at some point as well.
Objects of type Date
in Java are used to represent a specific instant in time. It also allows converting and parsing dates however the methods that provided this are now deprecated .
Instead the Class Calendar
for conversions and date arithmetic, this class also provides the ability to work with different Locales
and represent dates in different languages or calendar types specify.
Converting objects Date
to Calendar
is simple:
Date d = new Date(); // Crea el objeto Date
Calendar calendar = Calendar.getInstance(); // Obtiene una instancia de Calendar
calendar.setTime(date); // Asigna la fecha al Calendar
Once you have an instance of Calendar
you can get information about the date as follows:
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
One thing to take into account is that months are considered integers from 0 to 11. In the documentation you can find all the available fields that you can consult.
If you have an instance of Calendar
and want to convert to date:
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
For parsing and formatting dates it is recommended to use the Class DateFormat
or some subclass like SimpleDateFormat
, for example:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String fecha = sdf.format(new Date());
System.out.println(fecha); // 27/01/2016
My suggestion is that you store your dates as objects Date
because they are easier objects to generate and if you need some conversion or operation like adding 5 months to a date use Calendar
and then go back to type Date
.
Finally DateTime
is not a data type in Java SE, it exists as part of a library called Joda Time , and offers a variety of additional methods to operate with dates.