Saturday, December 8, 2007

Java Calendar VS Date

Although Date is deprecated but still we cant use a java.util.calendar abstract class when we are looking forward to make a String like "8th December 2007" coz all the members of the Calendar class are int types
so code like
Calendar cal = new GregorianCalendar();
or
Calendar cal=Calendar.getInstance();
int i = cal.get(Calendar.VAR_OF_I);
will always give integer ....
// Gotcha warning: months go from 0 to 11

GregorianCalendar is the actual implementation of the abstract Calendar class and supplies good behavior

If you want to compare it to a different date time, you've got all you need in the date variable. If you want to display the value, use a date formatter to build a String in the desired format, & that's it.

One can convert Calendar object to Date object using getTime() method.

Think of java.util.Date as an abstract instant in time. It has no time zone, calendar, clock or any other structuring we've put on time. A Date only knows how many milliseconds had elapsed since Jan 1, 1970 00:00 UTC when this instant occurred
Date testDate = calendarObject.getTime();

The bottom line: if you just need to keep track of a date/time as most people do, just use a Date. If you need to also remember a specific time zone with it, choose Calendar. If you need to specifically use western calendar system, use GregorianCalendar.

using java.util.Date has one more advantage if one wants to move objects around over RMI. Calendar and Gregorian Calendar do not implement serializable. one could sub-class GregorianCalendar and make it serializable.

Even the Java Date object assumes that the date value stored is GMT. The value of the datetime that is displayed will depend on your location, or the location of the system that is generating that representation. For example, if I have an application on my machine in London and I view that Date object I would see 01April2002:10:00, now if that same Date object was used by a webserver on the east coast of the US to generate a web page it would generate 01April2002:05:00

To convert Calendar object to String

Calendar cal = Calendar.getInstance(TimeZone.getDefault());
String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getDefault());
String currentTime = sdf.format(cal.getTime());

Convert java.util.Date to java.sql.Date

java.sql.Date stores only date information, not times. Simply converting a java.util.Date into a java.sql.Date will silently set the time to midnight. So, to store date/times to be manipulated as java.util.Date objects, don’t do this

// BUG: loses time of day
preparedStatement.setDate(1, new java.sql.Date(date.getTime()));

do this instead:

preparedStatement.setTimestamp(1, new java.sql.Timestamp(date.getTime()));
java.sql.Timestamp is not a date

java.sql.Timestamp extends java.util.Date, but it should not be used as a Date. In JDK 1.3.1, Timestamp.getTime() (inherited from Date) returns the time to the nearest second only, but JDK 1.4.2 and JDK 1.5 it returns the time to the nearest millisecond as expected. So in JDK 1.3, when reading a timestamp from a ResultSet, don’t do this

// Java 1.3
java.util.Date d = resultSet.getTimestamp(1);
long millis = d.getTime(); // BUG: loses fractional seconds in JDK 1.3

To get the full date including milliseconds, you have to do this :

java.sql.Timestamp timestamp = resultSet.getTimestamp(1);
java.util.Date d = new java.util.Date(timestamp.getTime() +
timestamp.getNanos() / 1000000);

In JDK 1.4.2 and JDK 1.5, you can just do this, depending on what you’re going to do with the Date:

// Java 1.4+
java.util.Date d = resultSet.getTimestamp(1);

But this might be safer since it avoids any other potential Timestamp problems

// Java 1.4+
java.util.Date d = new java.util.Date(resultSet.getTimestamp(1).getTime());

If your code needs to run on JDK 1.3 and later, you’ll have to do this:

java.sql.Timestamp timestamp = resultSet.getTimestamp(1);
long millis = (timestamp.getTime() / 1000) * 1000 + timestamp.getNanos() / 1000000;
java.util.Date d = new java.util.Date(millis);

3 comments:

Anonymous said...

Is there an easy way to convert Calendar to a Date and vice-versa without using the deprecated methods of Date?

Anonymous said...

Great, It very useful.
Thank you.

Anonymous said...

Yes there is!

Date -> Calendar:
Calendar cal = new GregorianCalendar();
cal.setTime( date );

Calendar -> Date:
Date date = cal.getTime();

The first one (date -> calendar) works fine, the second one I haven't tried but according to the API is should work.