marcus
marcus

Reputation: 5199

Java Date and Calendar

I'm aware that Java 8 has a much improved date and time library based on Joda Time, but I'm very curious about the decisions made in the old libraries. I haven't found any good explanation about the java.util.Date constructor deprecation rationale (the closest question I've found is this: Difference between new Date() and Calendar date but it doesn't ask about deprecated methods/constructors and doesn't have an accepted answer).

The constructor java.util.Date(year, month, day) is considered deprecated and we should use new GregorianCalendar(year + 1900, month, date). If we call getTime() (which returns a Date...) on the Calendar instance, what have we gained, other than avoiding a deprecated constructor? Even java.sql.Date.toLocalDate uses some deprecated methods internally.

I have a codebase littered with this pattern (new GregorianCalendar followed by getTime) just to avoid the deprecated methods of java.util.Date (I need java.util.Date and java.sql.Date in JPA and JDBC), but I'm not sure what's the point or what was the point back then (*).

(*) Nowadays I can finally change them all to LocalDate because that's what I really needed anyway — saving what the user typed in without any timezone conversions.

Upvotes: 1

Views: 668

Answers (2)

Edwin Buck
Edwin Buck

Reputation: 70979

The old libraries permitted the construction of java.util.Date items from entries in a Gregorian calendar, by passing in the year, month, day, etc items.

This was problematic for a number of reasons. First, the Gregorian calendar system is a hybrid calendar system that transitioned from the Julian calendar system. This transition included the need to "skip" dates to realign the Julian calendar system with the seasons. So, there are missing days. Surprisingly, the java.util.Date does a decent job of capturing this behavior, except:

  • The dates to be skipped are dependent on when the transition was adopted, which mostly maps out to be Locale dependent.
  • The strong binding to the Gregorian Calendar of the core java.util.Date object means that implementing other calendar systems is problematic, as you need to implement them on top of a Gregorian System.
  • The date being tied to Locale and TimeZone also meant that you had to adjust the platform's Locale and TimeZone to get the appropriate Date behavior you wished, often adjusting it back for out-of local date computations.

The new calendar system attempts to avoid this by:

  • Having an API that passes in a field to set with the value, preventing direct binding of the calendar fields to the API methods.
  • Having an API that permits subclassing a Calendar such that one could implement calendars with vastly different definitions of months, days, and years (think lunar calendars, Jewish calendars, Arabic Calendars, Chinese Calendars, etc).

Going forward, one should use java.util.Date only as a thin wrapper around a timestamp, and that's more to have compatibility with the older APIs. All Date manipulations should be done in the appropriate Calendar instance.

Upvotes: 1

Andreas
Andreas

Reputation: 159260

See second paragraph in the javadoc of java.util.Date:

Prior to JDK 1.1, the class Date had two additional functions. It allowed the interpretation of dates as year, month, day, hour, minute, and second values. It also allowed the formatting and parsing of date strings. Unfortunately, the API for these functions was not amenable to internationalization. As of JDK 1.1, the Calendar class should be used to convert between dates and time fields and the DateFormat class should be used to format and parse date strings. The corresponding methods in Date are deprecated.

So, to answer your question "What have we gained?", the answer is "support for internationalization":

  • Ability to specify time zone (using Calendar).

  • Ability to use non-Gregorian calendar (using Calendar).

  • Ability to use localized formatting and parsing of date strings (using DateFormat).

Upvotes: 3

Related Questions