Differences between Date, DateTime and Calendar in Java 7

3

I am using Java 7 to develop an application to schedule conferences.

I have seen that there are several types of data to handle the 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 ?

    
asked by Gemasoft 27.01.2016 в 08:33
source

2 answers

3

From the documentation of java.util.Date (translated):

  

The Date class represents a specific moment in time, with millisecond precision.

While java.util.Calendar (translated, emphasis mine) :

  

The Calendar class is an abstract class that provides methods to convert between a specific moment in time and a set of calendar fields such as YEAR (year), MONTH (month), DAY_OF_MONTH (day of the month), HOUR (hour) and so on, and to manipulate the fields of the calendar, how to obtain the date of next week.

The biggest problem here in the design of the class Date is that it is mutable, when it should have been 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 Date data. In Java 8 this was solved by implementing a new internal framework for managing dates and times called Java 8 Date and Time and the classes can be found under the java.time package (your question is based on Java 7, so I only mention this part of Java 8, not I will go deeper in this point).

To use Calendar , I recommend you always initialize it in the following way:

Calendar calendar = Calendar.getInstance();

Since there is more than one implementation of Calendar , being the most 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 that for Java 8 is implemented in the following way (reviewing the source code of HotSpot):

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 by working directly with the implementation. This is covered here: link

I do not know any class DateTime declared in the JDK 7. Maybe you mean the class org.joda.time.DateTime of the library Joda Time (curious name in Spanish), which emerges as a solution to avoid working with Date that is mutable. DateTime is immutable and the operations you perform on a DateTime will actually create a new instance of DateTime instead of modifying the current instance.

If you want to know which class you should use in your projects, I would give you the following recommendations:

  • For your entities, declare the fields of type Date (make sure they are from the package java.util ).
  • To perform operations on Date like adding or removing time, there are 2 options:
    • Create an object of type Calendar , set its time from an instance of Date via Calendar#setTime , perform the necessary operations, and get the Date of Calendar via Calendar#getTime .
    • Procedure similar to the one described above, but using DateTime of Joda.
  • If you want to represent a date and time textually, I recommend using SimpleDateFormat#format(Date) (eye, get Date and not Calendar ) and avoid using the Date#getXyz methods. You could also use Calendar#get(Calendar.<campo>) but the code would be very verbose (I do not know a translation of this).

Why not directly declare the use of DateTime in the fields of your entities? Well, because there are frameworks that do not support direct conversion unless you implement particular converters for it. Some examples: Hibernate 1 , JSF, Spring, etc.

1 Hibernate 5 now offers support for the Date Time library of Java 8. I suppose that the frameworks will gradually go down that path at some point too.

    
answered by 27.01.2016 / 16:13
source
3

Objects of type Date in Java are used to represent a specific moment in time. It also allows converting and parsing dates however the methods that provided this are now deprecated .

Instead the class Calendar is used for conversions and date arithmetic, this class also provides the ability to work with different Locales and represent dates in different languages or specific calendar types.

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 in the following way:

int year        = calendar.get(Calendar.YEAR);
int month       = calendar.get(Calendar.MONTH);
int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);

One thing to keep in mind is that the months are considered whole 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 as 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 Date objects because they are easier to generate objects and if you need any conversion or operation such as adding 5 months to a date you use Calendar and then return to the 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.

    
answered by 27.01.2016 в 16:13