Tuesday, April 11, 2023

How to Convert java.util.Date to java.sql.Date - Example

Hello guys, you may not know but there are two date classes in Java, one in java.util package and other in the java.sql package. Though both are known as Date class, there is some difference between java.util.Date and java.sql.Date e.g. Former is used whenever a Date is required in Java application while later is used to read and store DATE SQL type from the database. There is one more important difference is, java.util.Date stores both date and time values, while java.sql.date only stores date information, without any time part. As per Javadoc, java.sql.date is a thin wrapper around a millisecond value that allows JDBC to identify this as an SQL DATE value. To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated. See SQL date vs Util date for few more differences.

In this Java tutorial, we will learn how to convert a java.util.Date to java.sql.Date, as we often need to do this when storing values into database. Since java.util.Date is standard way to represent date and time in Java, I only keep java.sql.Date up-to JDBC or DAO Layer, by the way if you need date with time, then use SQL TIMESTAMP type instead of DATE.

It's also notable that java.sql.Date is subclass of java.util.Date, but it doesn't mean you can pass around this in place of java.util.Date, because it violates Liskov Substitution principle.




All time related methods of java.sql.Date throws IllegalArgumentException, as shown below


public int getHours() {
    throw  java.lang.IllegalArgumentException();
}
 
public int getMinutes() {
    throw new java.lang.IllegalArgumentException();
}


public int getSeconds() {
    throw new java.lang.IllegalArgumentException();
}

It actually an interesting case of Inheritance, where superclass is more powerful than subclass, and instead of extending functionalities of parent class, subclass is actually limiting feature by not allowing time fields. If you have a code, which accepts java.util.Date, compiler will allow a java.sql.Date to be passed to that method, but as soon as you run the program, your code will fail with following error :

Exception in thread "main" java.lang.IllegalArgumentException
    at java.sql.Date.getHours(Date.java:182)

That's why, make sure not to let java.sql.Date come outside of Data Access layer. By the way, because both the class has same name Date, you can not use them together by their simple name, you need to specify their fully quality name, i.e. name with package, as shown in below example. If we import java.util.Date then compiler will treat any Date as util date and not java.sql.Date.


Java Program to convert java.util.Date to java.sql.Date

Here is our sample program for converting a util date to sql date. Since both Date classes are based upon long time interval, you can easily convert them by passing value of getTime(), which represent milliseconds passed from 1st January 1970, also known as EPOCH. Since java.sql.Date only contains date information, any time information supplied to it are ignored or normalized. 

This is obvious when you print values of both date classes, java.util.Date prints both date and time component, while SQL date prints only information in dateformat yyyy-MM-dd

You can also call to time-related methods from java.sql.Date e.g. getHours(), getMinutes() and getSeconds()  are failed by throwing java.lang,.IllegalArgumentException. That's why it's advised not to pass a SQL date to a method, which expect a util date in Java.


/**
 * Java Program to convert java.util.Date into java.sql.Date
 * @author http://java67.blogspot.com
 */
public class DateConverter {
 
    public static void main(String args[]) {
 
        // contains both date and time information
        java.util.Date utilDate = new java.util.Date();
        System.out.println("Util date in Java : " + utilDate);
 
        // contains only date information without time
        java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
        System.out.println("SQL date in Java : " + sqlDate);
        System.out.printf("Time :  %s:%s:%s", sqlDate.getHours(), sqlDate.getMinutes(),
                sqlDate.getSeconds());
 
    }
 
}
 
Output:
Util date in Java : Mon Feb 03 13:26:05 PST 2014
SQL date in Java : 2014-02-03
Exception in thread "main" java.lang.IllegalArgumentException
    at java.sql.Date.getHours(Date.java:182)

That's all about how to convert java.util.Date to java.sql.Date in Java. Always use getTime() method to convert one date to other. Also remember that sql date in Java only holds date information without time. Though java.sql.Date is a subclass of java.util.Date it violates Liskov substitution principle, and can not be passed where java.util.Date is expected. Compiler will allow that but it will fail in runtime if you call any time related method, they are anyway deprecated, so don't use them.


7 comments:

  1. pro tip: you can just store datetime as long. works great w/ .js clients.

    ReplyDelete
  2. i need java.sql.date in the follwoing format "MM-dd-yyyy" and it should not be a String after formatting, it should be same java.sql.date.

    ReplyDelete
    Replies
    1. N Pradeep, when you say formatting which always mean String. Since Date is stored in long time millisecond you can alway format into String based upon your requirement. So your requirement is not possible because java.sql.Date keeps data value as long not String.

      Delete
  3. I am getting illegalArgument exception error... How to access Date (util date) from file to store it in list.. The file contains date which is a util date..we use value of in case of SQL date then how to access util date?

    ReplyDelete
    Replies
    1. Can you post your code? It looks like that your code is expecting java.sql.Date and you are passing java.util.Date, but can't say much until I see the portion of the code throwing error. Also, please post error message.

      Delete
  4. upload tutorial for work withhibernate

    ReplyDelete
    Replies
    1. That's a great idea, thx for suggestion, noted.

      Delete

Feel free to comment, ask questions if you have any doubt.