views:

2081

answers:

8

Could someone please advise the current "best practice" around Date and Calendar types.

When writing new code, is it best to always favour Calendar over Date, or are there circumstances where Date is the more appropriate datatype?

+21  A: 

Date is a simpler class and is mainly there for backward compatibility reasons. If you need to set particular dates or do date arithmetic, use a Calendar. Calendars also handle localization. The previous date manipulation functions of Date have since been deprecated.

Personally I tend to use either time in milliseconds as a long (or Long, as appropriate) or Calendar when there is a choice.

Both Date and Calendar are mutable, which tends to present issues when using either in an API.

cletus
+1 one for answering a Java date question without mentioning Joda Time!!!
Mark
Or jQuery...? :)
cletus
or Father Christmas ? :)
Adrian Pronk
+5  A: 

Date is best for storing a date object. It is the persisted one, the Serialized one ...

Calendar is best for manipulating Dates.

Note: we also sometimes favor java.lang.Long over Date, because Date is mutable and therefore not thread-safe. On a Date object, use setTime() and getTime() to switch between the two. For example, a constant Date in the application (examples: the zero 1970/01/01, or an applicative END_OF_TIME that you set to 2099/12/31 ; those are very useful to replace null values as start time and end time, especially when you persist them in the database, as SQL is so peculiar with nulls).

KLE
I take it you are taking about the immutable `java.lang.Long`
pjp
Correct. I improved my answer to reflect your nice comment. Thanks.
KLE
+10  A: 

The best way for new code (if your policy allows third-party code) is to use the Joda Time library.

Both, Date and Calendar, have so much design problems that both are not good solutions for new code.

dmeister
I second the suggestion to use joda time. It is easier to use and understand and offers much more functionality you can use.
Jeroen van Bergen
For discussion on whether to use Joda Time or stick with standard JDK classes, see http://stackoverflow.com/questions/589870/should-i-use-java-date-and-time-classes-or-go-with-a-3rd-party-library-like-joda
Jonik
How other frameworks co-exists with that? is it supported out of the box or do you need to write some extra converters?
01
+2  A: 
  • Date and Calendar are really the same fundamental concept (both represent an instant in time and are wrappers around an underlying long value).

  • One could argue that Calendar is actually even more broken than Date is, as it seems to offer concrete facts about things like day of the week and time of day, whereas if you change its timeZone property, the concrete turns into blancmange! Neither objects are really useful as a store of year-month-day or time-of-day for this reason.

  • Use Calendar only as a calculator which, when given Date and TimeZone objects, will do calculations for you. Avoid its use for property typing in an application.

  • Use SimpleDateFormat together with TimeZone and Date to generate display Strings.

  • If you're feeling adventurous use Joda, although it is unnecessarily complicated IMHO and is soon to be superceded by the JSR-310 date API in any event.

  • I have answered before that it is not difficult to roll your own YearMonthDay class, which uses Calendar under the hood for date calculations. I was downvoted for the suggestion but I still believe it is a valid one because JODA (and JSR-310) are really so over-complicated for most use-cases

oxbow_lakes
Is there a time frame for JSR310 ? It was going to be in Java 7, but I believe that's now not the case.
Brian Agnew
@Brian - it's certainly gone very quiet on that mailing list!
oxbow_lakes
Just checking, it's gone Inactive, which means they've not published a milestone draft in 18 months :-(
Brian Agnew
Most recent comment on the mailing list is from July and by Stephen, so the project is probably still ticking away
oxbow_lakes
+3  A: 

I always advocate Joda-time. Here's why.

  1. the API is consistent and intuitive. Unlike the java.util.Date/Calendar APIs
  2. it doesn't suffer from threading issues, unlike java.text.SimpleDateFormat etc. (I've seen numerous client issues relating to not realising that the standard date/time formatting is not thread-safe)
  3. it's the basis of the new Java date/time APIs (JSR310, once scheduled for Java 7, but I think they're delayed). So you'll be using APIs that will become core Java APIs.
Brian Agnew
The last time I looked, JODA and JSR-310 looked *very* different, even if they are both written by Stephen Colebourne. That said, JODA would introduce you to the complexity of the date-time problems that JSR-310 also solves
oxbow_lakes
+1  A: 

Dates should be used as immutable points in time; Calendars are mutable, and can be passed around and modified if you need to collaborate with other classes to come up with a final date. Consider them analogous to String and StringBuilder and you'll understand how I consider they should be used.

(And yes, I know Date isn't actually technically immutable, but the intention is that it should not be mutable, and if nothing calls the deprecated methods then it is so.)

Andrzej Doyle
A: 

Is it a good practice to pass Calendar instance in your public api ?

Anthos
I personally would only use Dates in my public API just because I prefer immutable values.
Archimedes Trajano
+1  A: 

I generally use Date if possible. Although it is mutable, the mutators are actually deprecated. In the end it basically wraps a long that would represent the date/time. Conversely, I would use Calendars if I have to manipulate the values.

You can think of it this way: you only use StringBuffer only when you need to have Strings that you can easily manipulate and then convert them into Strings using toString() method. In the same way, I only use Calendar if I need to manipulate temporal data.

For best practice, I tend to use immutable objects as much as possible outside of the domain model. It significantly reduces the chances of any side effects and it is done for you by the compiler, rather than a JUnit test. You use this technique by creating private final fields in your class.

And coming back to the StringBuffer analogy. Here is some code that shows you how to convert between Calendar and Date

String s = "someString"; // immutable string
StringBuffer buf = new StringBuffer(s); // mutable "string" via StringBuffer
buf.append("x");
assertEquals("someStringx", buf.toString()); // convert to immutable String

// immutable date with hard coded format.  If you are hard coding the format, best practice
// is to hard code the locale of the format string, otherwise people in some parts of Europe
// are going to be mad at you.
Date date =     new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2001-01-02");

// Convert Date to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);

// mutate the value
cal.add(Calendar.YEAR, 1);

// convert back to Date
Date newDate = cal.getTime();

// 
assertEquals(new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2002-01-02"), newDate);
Archimedes Trajano