java.sql.Date is not a real date

Thursday, 14 August 2003

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 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);

For more information, see the Javadoc for java.sql.Timestamp.
JDK 1.3.1 TimeStamp Javadoc
JDK 1.4.2 TimeStamp Javadoc
JDK 1.5.0 TimeStamp Javadoc

Note the subtle difference between 1.3.1 and the later ones: The following lines appear in the 1.3.1 Javadoc, but were removed in subsequent version.

The getTime method will return only integral seconds. If a time value that includes the fractional seconds is desired, you must convert nanos to milliseconds (nanos/1000000) and add this to the getTime value.

See also the amusing notes on Bug 4679060 on developers.sun.com.

Tags:

36 comments

You can leave a comment, or trackback from your own site.

  1. Sir,
    i have one doubt, i have get the date from date picker to textbox. That date will converted to SqlDate. But error will be displayed. That error has been optional feature has been not availble. This error has what type of error.? Please send to me.

  2. Mr. Saravanakumar,

    I believe you are from India – Tamilnadu. You need to improve your english.

  3. import java.util.*;
    import java.text.*;

    public class ShowToday {
    public static void main(String args[]) {
    ShowToday st = new ShowToday();
    st.demo();
    }
    public void demo() {
    System.out.println(easyDateFormat(“dd MMMMM yyyy”));
    System.out.println(easyDateFormat(“yyyyMMdd”));
    System.out.println(easyDateFormat(“dd.MM.yy”));
    System.out.println(easyDateFormat(“MM/dd/yy”));
    System.out.println(easyDateFormat(“yyyy.MM.dd G ‘at’ hh:mm:ss z”));
    System.out.println(easyDateFormat(“EEE, MMM d, ”yy”));
    System.out.println(easyDateFormat(“h:mm a”));
    System.out.println(easyDateFormat(“H:mm:ss:SSS”));
    System.out.println(easyDateFormat(“K:mm a,z”));
    System.out.println(easyDateFormat(“yyyy.MMMMM.dd GGG hh:mm aaa”));
    public String easyDateFormat (String format) {
    Date today = new Date();
    SimpleDateFormat formatter = new SimpleDateFormat(format);
    String datenewformat = formatter.format(today);
    return datenewformat;
    }
    }

  4. chukked, please elaborate!

  5. Hi,

    I wanted to know what are the main differences between the java versions 1.3.0 and 1.4.1 or later especially in case of java.util.Date.
    In our application previously we were using the java version1.3.0 now we are planning to go for java version1.4.1or later. Is there any code impact on the previous version.

  6. Soori, the Java SDKs contain the library source code. You can compare them yourself to find out all the differences.

  7. W. Paul Caligiuri

    Great Job! Very Helpful!

  8. Very good work. Saved my time.

  9. Thanks for the terse and thorough work!

  10. Thanks very much for posting this information. It was really helpful.

  11. I will input data in oracle.

    java.sql.Date object,

    but, java.sql.Date is “2007-01-02”,

    I hope input in oracle, java.sql.Date is “2007-01-02 23:12:50”.

  12. When I convert java.util.Date into java.sql.Date how can I set a default time other than midnight? Specifically, I know that I need to set 12:00 noon. Must I ireriate over every row, or can I set a default?

    Thanks in advance.

  13. Very good explanation ! Saved me a lot of grief

  14. Thank you thank you thank you for posting this!!! I had really been struggling with that. You are a lifesaver!

  15. Thanks a lot for this posting! It saved me a lot of time trying……..

  16. “Last morning this post saved my life”.

    Thank u very much. I think Java dates management is too obscure and complex.

  17. how to convert date in yymmmdd format to mm/dd/yy format in java like Convert ’97Jan02′ to 01/02/97

  18. Sir,
    i have one doubt, i am using struts 2.1 datepicker tag. how this date get converted into sql3 date format.Please reply the solution.
    in advance thanx.

  19. i am chinese boy,and i an english poor,but i want to say thank you!

  20. Seeing something weird; when input date to java.sql.Date, am getting return in which month is always 1; as in:

    Date dateOfBirth = null;
    SimpleDateFormat dateFmt = new SimpleDateFormat(“mm/dd/yyyy”);
    Timestamp disableDate = new Timestamp(dateFmt.parse(((String) e.getValue()).trim()).getTime());
    dateOfBirth = new java.sql.Date(disableDate.getTime())

    where dateOfBirth is 07/06/1956, I consistently get 1956-01-06

    Any particular reason for this?

    thnx

Leave a comment