tags:

views:

2042

answers:

4

I'm pulling back a Date and a Time from a database. They are stored in separate fields, but I would like to combine them into a java.util.Date object that reflects the date/time appropriately.

Here is my original approach, but it is flawed. I always end up with a Date/Time that is 6 hours off what it should be. I think this is because the Time has a timezone offset as well as the Date, and I really only need one of them to have the timezone offset.

Any suggestions on how to do this so that it will give me the correct Date/Time?

import java.sql.Time;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.time.DateUtils;
    public static Date combineDateTime(Date date, Time time)
        {
         if (date == null)
          return null;
         Date newDate = DateUtils.truncate(date, Calendar.DATE);
         if (time != null)
         {
          Date t = new Date(time.getTime());
          newDate = new Date(newDate.getTime() + t.getTime());
         }
         return newDate;
        }
+6  A: 

I would put both the Date and the Time into Calendar objects, and then use the various Calendar methods to extract the time values from the second object and put them into the first.

  Calendar dCal = Calendar.getInstance();
  dCal.setTime(date);
  Calendar tCal = Calendar.getInstance();
  tCal.setTime(time);
  dCal.set(Calendar.HOUR_OF_DAY, tCal.get(Calendar.HOUR_OF_DAY));
  dCal.set(Calendar.MINUTE, tCal.get(Calendar.MINUTE));
  dCal.set(Calendar.SECOND, tCal.get(Calendar.SECOND));
  dCal.set(Calendar.MILLISECOND, tCal.get(Calendar.MILLISECOND));
  date = dCal.getTime();
Paul Tomblin
Calendar.getInstance() creates a new instance of Calendar every single call. Calendar is very heavy weight, and not thread safe. While this is technically a correct way of doing it, there are much better ways of going about it.
Spencer K
If there is a better way could you please post it?
ScArcher2
Well, if you're concerned about creating too many Calendars, you can create one for the date portion and one for the time, and just keep resetting them with dCal.setTime(date) and tCal.setTime(time);
Paul Tomblin
+5  A: 

Use Joda Time instead of Java's own Date classes when doing these types of things. It's a far superior date/time api that makes the sort of thing you are trying to do extremely easy and reliable.

Steve McLeod
+1  A: 

Assuming you know the time zone of the time being read from the database you need to use the ResultSet.getTime(String, Calendar) method having previously set the time zone on the Calendar. The JDBC driver will make the necessary adjustments to the time.

If all code is running serverside I'd strongly recommend standardizing on common time zone (probably UTC) for all times and converting as appropriate when displaying rendering in the GUI.

I'd also use JodaTime (http://joda-time.sourceforge.net), it'll save you headaches in the future.

Nick Holt
+2  A: 

@Paul Tomblin is a sure way to control the TimeZone issue, and I knew someone was going to throw "Joda Time" into the mix. The other answers are all good and more robust than the following hack:

If your application executes in the same TimeZone as is the default in the DB, you might be able to get away with the following:

If you skip this step:

Date t = new Date(time.getTime());

and use the java.sql.Time value directly, like:

newDate = new Date(newDate.getTime() + time.getTime());

the conversion to the default TimeZone won't be introduced - the java.sql.Time should contain the value as stored.

YMMV, caveat emptor, etc...

Ken Gentle