Merge java.util.date with java.sql.Time

20,569

Solution 1

java.sql.Time is just a wrapper over the java.util.Date. You can use it as if you would add two java.util.Date objects.

For example, set Calendar to java.sql.Time:

calendar.setTime(time);

Now extract the hour/minute/seconds fields, i.e.:

calendar.get(Calendar.HOUR);

Next, set the Calendar to java.util.Date object and add these three fields to its time, i.e.:

calendar.add(Calendar.HOUR, hour);

And get the Date back:

calendar.getTime();

Solution 2

Easiest way would be to just add the milli secs together to create a new date, ala

public static Date getDate(Date date, Time time) {
    return new Date(date.getTime() + time.getTime())
}

Solution 3

vickirk's solution wasn't so bad, but has timezone issues, which results in the one hour less you observed.

I suppose, BST means British Summer Time, which is GMT +0100. Now, java.util.Date and its descendants internally work with numbers of milliseconds since midnight Jan 01, 1970 GMT. The timezone is not taken into account until you stringfy the date/time with toString(). And they use your local timezone for that, which is BST, apparently. That means, what is really stored in these objects, is

java.util.date: Mon May 09 23:00:00 GMT 2011
java.sql.time: 02:58:44 GMT

When you add the internal values (which are retrieved by getTime()) like vickirk suggested, you obtain a date which contains
Tue May 10 01:58:44 GMT 2011, which then results in
Tue May 10 02:58:44 BST 2011 on stringification.

So the explanation for the one hour less is that the timezone offset applies twice, when you stringified the values separately, whereas it applies only once after the addition, because you stringfy only once now. Or, from another point of view, adding the internal value of the point in time 03:58:44 BST is equivalent to adding a time span of 2h 58m 44s.

So to get a time span of 3h 58m 44s encoded in a java.sql.Time, you have to make up for the time zone offset manually. You do that by parsing the time string "00:00:00" with java.sql.Time, which will result in an internal value of -3600000 which is equivalent to 31 Dec 1969 23:00:00 GMT, i.e. one hour before the epoch. This is the negative of the time zone offset.

public static Date mergeDate(Date date, Time time) {
    long tzoffset = -(Time.valueOf("00:00:00").getTime());
    return new Date(date.getTime() + time.getTime() + tzoffset);
}

Of course, all this is a dirty hack, which is necessary because you insist on interpreting the Time's value as a time span, while it really is a point in time.

Solution 4

Instead, you can use this.

   public static Date getDate(Date date, Time time) {
        Calendar calendar=Calendar.getInstance();
        calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
        calendar.setTime(date);
        calendar.add(Calendar.MILLISECOND, (int) time.getTime());
        return calendar.getTime();
    }

Solution 5

Can you do

java.util.Date newDate = new java.util.Date(sqlDate.getTime());
Share:
20,569
marcolopes
Author by

marcolopes

Updated on September 06, 2020

Comments

  • marcolopes
    marcolopes over 3 years

    I have an extensive DATE-TIME conversion class, but i came across a scenario that i cannot resolve:

    I have a java.util.date: Tue May 10 00:00:00 BST 2011
    I have a java.sql.time: 03:58:44

    I need to create a java.util.date: Tue May 10 03:58:44 BST 2011

    The only approach i came up with is:

    public static Date getDate(Date date, Time time) {
        Calendar calendar=Calendar.getInstance();
        calendar.set(date.getYear(), date.getMonth(), date.getDay(), time.getHours(), time.getMinutes(), time.getSeconds());
        return calendar.getTime();
    }
    

    Totally deprecated code, and does not work: java.lang.IllegalArgumentException at java.sql.Time.getYear(Unknown Source)

    Any ideas?

  • marcolopes
    marcolopes almost 13 years
    That was my first try... it returns: Thu Jan 01 03:59:26 GMT 1970 :-\ So, the TIME is ok, but resets all other fields.
  • Jeremy
    Jeremy almost 13 years
    java.sql.Time is a java.util.Date ;-)
  • marcolopes
    marcolopes almost 13 years
    Sorry, it works, But i get one hour less. Tue May 10 00:00:00 BST 2011 & 03:58:44 = Tue May 10 02:58:44 BST 2011
  • marcolopes
    marcolopes almost 13 years
    Works, But i get one hour less... Tue May 10 00:00:00 BST 2011 & 03:58:44 = Tue May 10 02:58:44 BST 2011
  • Manoj
    Manoj almost 13 years
    That is because you need to set the timezone properly. use setTimezone() method of the calendar.
  • marcolopes
    marcolopes almost 13 years
    I'm confused... java.util.date does not hold the timezone?
  • marcolopes
    marcolopes almost 13 years
    Just a remark: we must use HOUR_OF_DAY to respect the 24 hour format.
  • marcolopes
    marcolopes almost 13 years
    I cannot think of a better way to "merge" a DATE (with no "time" information) with an Sql Time (with no "date" information). I need to compare dates, and one of the sources is an SQL table that gives me a DATE and a TIME that i must put together.