514

I am trying to use a java.util.Date as input and then creating a query with it - so I need a java.sql.Date.

I was surprised to find that it couldn't do the conversion implicitly or explicitly - but I don't even know how I would do this, as the Java API is still fairly new to me.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
David Ackerman
  • 12,649
  • 6
  • 24
  • 19
  • You can find a similar issue here http://stackoverflow.com/questions/12131068/error-casting-java-util-date-into-java-sql-date – Lem Oct 29 '13 at 09:59
  • For me, it turned out I didn't needed to convert. There was a `import java.sql.*` in my code, overriding the java.util.date and thus causing trouble when assigning date values that were fine with the latter but not the first. HTH – HumanInDisguise Apr 28 '15 at 13:36
  • 1
    @DavidAckerman Do you understand that a java.util.Date is a date *and* a time-of-day, but a java.sql.Date is only a date *without* a time-of-day? (Actually there is a time-of-day but that is ignored, a bad hack of a class design) In SQL, `DATE` means date-only. – Basil Bourque Sep 24 '15 at 20:58
  • 2
    I indeed wasn't aware of the nuances back in '09, and since this question is so popular, I've changed the accepted answer to one that is both more modern and complete. Thanks everyone for your input! – David Ackerman Dec 05 '16 at 15:06

17 Answers17

530

Nevermind....

public class MainClass {

  public static void main(String[] args) {
    java.util.Date utilDate = new java.util.Date();
    java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
    System.out.println("utilDate:" + utilDate);
    System.out.println("sqlDate:" + sqlDate);

  }

}

explains it. The link is http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm

David Ackerman
  • 12,649
  • 6
  • 24
  • 19
  • 35
    This is not an explicit conversion! From the Javadoc: "If the given milliseconds value contains time information, the driver will set the time components to the time in the default time zone (the time zone of the Java virtual machine running the application) that corresponds to zero GMT." So no matter what your time on your java.util.Date, it will be inserted as 00:00:00 in a column with the data type set to DATE. –  Apr 12 '12 at 19:43
  • 1
    @David Ackerman.....this method returns the `epochseconds` i.e milliseconds after `1,JAN,1970`. But What if we want to store the date of a person before this date....or something like `0000-00-00 as default` – Arjun K P Jun 27 '12 at 17:27
  • 31
    In my case the correct answer is java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(utilDate.getTime());, because it preserves the time fields. – Alberto de Paola Sep 03 '12 at 23:05
  • @ArjunKP A java `long` can be assigned negative numbers, and that's negative numbers for in a Date. – Amir Pashazadeh Jun 14 '13 at 09:03
  • It begs the question, why there are two different `Date` objects which are incompatible as part of java's design? Shouldn't it be named `SQLDate` or something instead of `Date`? – wired00 Feb 04 '15 at 01:11
  • 2
    @wired00 Yes, the **old date-time classes** bundled with the early versions of Java **are a mess**, badly designed including some crude hacks. Whenever possible, try to use the new [java.time framework](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) in Java 8 and later. These new classes supplant the old. The java.time classes and the old classes have some convenience methods for converting back and forth -- useful while we wait for JDBC drivers to be updated to directly utilize the new java.time types. – Basil Bourque Jul 06 '15 at 03:52
  • @BasilBourque thanks very much on java.time will check into it – wired00 Jul 06 '15 at 04:27
  • 2
    @wired00 See [my new Answer](http://stackoverflow.com/a/31238011/642706) on this Question for how to use java.time. Also search StackOverflow for many more examples. – Basil Bourque Jul 06 '15 at 05:01
134

tl;dr

How to convert java.util.Date to java.sql.Date?

Don’t.

Both Date classes are outmoded. Sun, Oracle, and the JCP community gave up on those legacy date-time classes years ago with the unanimous adoption of JSR 310 defining the java.time classes.

  • Use java.time classes instead of legacy java.util.Date & java.sql.Date with JDBC 4.2 or later.
  • Convert to/from java.time if inter-operating with code not yet updated to java.time.
Legacy Modern Conversion
java.util.Date java.time.Instant java.util.Date.toInstant()
java.util.Date.from( Instant )
java.sql.Date java.time.LocalDate java.sql.Date.toLocalDate()
java.sql.Date.valueOf( LocalDate )

Example query with PreparedStatement.

myPreparedStatement.setObject( 
    … ,                                         // Specify the ordinal number of which argument in SQL statement.
    myJavaUtilDate.toInstant()                  // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC).
        .atZone( ZoneId.of( "Africa/Tunis" ) )  // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`.
        .toLocalDate()                          // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object.
)

Replacements:

  • Instant instead of java.util.Date
    Both represent a moment in UTC. but now with nanoseconds instead of milliseconds.
  • LocalDate instead of java.sql.Date
    Both represent a date-only value without a time of day and without a time zone.

Details

If you are trying to work with date-only values (no time-of-day, no time zone), use the LocalDate class rather than java.util.Date.

Table of date-time types in Java (both legacy and modern) and in the SQL standard.

java.time

In Java 8 and later, the troublesome old date-time classes bundled with early versions of Java have been supplanted by the new java.time package. See Oracle Tutorial. Much of the functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.

A SQL data type DATE is meant to be date-only, with no time-of-day and no time zone. Java never had precisely such a class† until java.time.LocalDate in Java 8. Let's create such a value by getting today's date according to a particular time zone (time zone is important in determining a date as a new day dawns earlier in Paris than in Montréal, for example).

LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );  // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".

At this point, we may be done. If your JDBC driver complies with JDBC 4.2 spec, you should be able to pass a LocalDate via setObject on a PreparedStatement to store into a SQL DATE field.

myPreparedStatement.setObject( 1 , localDate );

Likewise, use ResultSet::getObject to fetch from a SQL DATE column to a Java LocalDate object. Specifying the class in the second argument makes your code type-safe.

LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );

In other words, this entire Question is irrelevant under JDBC 4.2 or later.

If your JDBC driver does not perform in this manner, you need to fall back to converting to the java.sql types.

Convert to java.sql.Date

To convert, use new methods added to the old date-time classes. We can call java.sql.Date.valueOf(…) to convert a LocalDate.

java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );

And going the other direction.

LocalDate localDate = sqlDate.toLocalDate();

Converting from java.util.Date

While you should avoid using the old date-time classes, you may be forced to when working with existing code. If so, you can convert to/from java.time.

Go through the Instant class, which represents a moment on the timeline in UTC. An Instant is similar in idea to a java.util.Date. But note that Instant has a resolution up to nanoseconds while java.util.Date has only milliseconds resolution.

To convert, use new methods added to the old classes. For example, java.util.Date.from( Instant ) and java.util.Date::toInstant.

Instant instant = myUtilDate.toInstant();

To determine a date, we need the context of a time zone. For any given moment, the date varies around the globe by time zone. Apply a ZoneId to get a ZonedDateTime.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();

† The java.sql.Date class pretends to be date-only without a time-of-day but actually does a time-of-day, adjusted to a midnight time. Confusing? Yes, the old date-time classes are a mess.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

Table of which java.time library to use with which version of Java or Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 1
    "While you should avoid using the old date-time classes, you may be forced to when working with existing code. If so, you can convert to/from java.time." Actually, no. This and the the Date.valueOf() are actually **not** available in the JDBC/Java7 paradigm. – sf_jeff Aug 17 '20 at 01:28
  • @sf_jeff Java 7 support is covered in the bullets at the end of my Answer: *Where to obtain the java.time classes?* – Basil Bourque Aug 19 '20 at 23:01
  • @Brain Reread *Convert to …* & *Converting from…* sections. To interoperate with old code not yet updated to *java.time*, do your business logic in *java.time*. At the edges convert between modern & legacy types by calling new methods added to the old classes. For `java.sql.Date`, see the [`toLocalDate`](https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/Date.html#toLocalDate()) and [`valueOf( LocalDate )`](https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/Date.html#valueOf(java.time.LocalDate)) methods. Never write new code using the old classes. – Basil Bourque Sep 24 '20 at 21:59
  • 1
    I downvoted this answer, but not because it is incorrect. The OP asked how to do it, not for a browbeating over the use of legacy date objects or whether there was a better / newer way. For all Basil knows, the OP was constrained to an older version of java or a library that only allowed for those two types, yada yada yada. – dnebing Jul 20 '21 at 22:37
  • @dnebing No browbeating intended. You may not realize just how terribly bad are the legacy date-time classes. Sun, Oracle, & the JCP community all gave up on these classes years ago with unanimous adoption of [JSR 310](https://jcp.org/en/jsr/detail?id=310). The *java.time* classes come bundled with Java 8 and later. All the legacy classes carry new methods for converting back-and-forth between legacy and modern objects. A back-port is available for Java 6 & 7, parallel API. That back-port is equipped with conversion methods as well. So there really is no reason to not be using *java.time*. – Basil Bourque Aug 04 '21 at 21:08
  • I know how bad they are. The OP probably knows how bad they are. The question wasn't about how bad they are, though, the question was just how to do it, and the answer should have stuck to that, IMHO. Don't get me wrong, your answer is absolutely right for the question "Should I still use java.util.Date or not?", so kudos for that. – dnebing Aug 06 '21 at 00:18
41

With the other answer you may have troubles with the time info (compare the dates with unexpected results!)

I suggest:

java.util.Calendar cal = Calendar.getInstance();
java.util.Date utilDate = new java.util.Date(); // your util date
cal.setTime(utilDate);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);    
java.sql.Date sqlDate = new java.sql.Date(cal.getTime().getTime()); // your sql date
System.out.println("utilDate:" + utilDate);
System.out.println("sqlDate:" + sqlDate);
mauretto
  • 3,183
  • 3
  • 27
  • 28
  • 5
    If he's using java.sql.Date for a Date column in a database, that time information will be truncated. You've overengineered the solution in my opinion. – darioo Nov 04 '10 at 14:12
  • 4
    Yes, maybe I did it. I sometimes need to compare the java.sql.Data with the current date and imho this is the best way. I hope it can help. – mauretto Nov 09 '10 at 09:14
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Dec 31 '18 at 00:38
  • Of course, this topic was about 10 yrs ago, pre-java 8. – mauretto Jan 08 '19 at 08:21
33

This function will return a converted SQL date from java date object.

public java.sql.Date convertJavaDateToSqlDate(java.util.Date date) {
    return new java.sql.Date(date.getTime());
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
chetan
  • 411
  • 1
  • 5
  • 8
21

Converting java.util.Date to java.sql.Date will lose hours, minutes and seconds. So if it is possible, I suggest you to use java.sql.Timestamp like this:

prepareStatement.setTimestamp(1, new Timestamp(utilDate.getTime()));

For more info, you can check this question.

Sébastien Temprado
  • 1,413
  • 4
  • 18
  • 29
shellbye
  • 4,620
  • 4
  • 32
  • 44
17

In my case of picking date from JXDatePicker (java calender) and getting it stored in database as SQL Date type, below works fine ..

java.sql.Date date = new java.sql.Date(pickedDate.getDate().getTime());

where pickedDate is object of JXDatePicker

jack jay
  • 2,493
  • 1
  • 14
  • 27
6

This function will return a converted SQL date from java date object.

public static java.sql.Date convertFromJAVADateToSQLDate(
            java.util.Date javaDate) {
        java.sql.Date sqlDate = null;
        if (javaDate != null) {
            sqlDate = new Date(javaDate.getTime());
        }
        return sqlDate;
    }
6

Format your java.util.Date first. Then use the formatted date to get the date in java.sql.Date

java.util.Date utilDate = "Your date"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
final String stringDate= dateFormat.format(utilDate);
final java.sql.Date sqlDate=  java.sql.Date.valueOf(stringDate);
hackfield
  • 57
  • 1
  • 4
2

Here the example of converting Util Date to Sql date and ya this is one example what i am using in my project might be helpful to you too.

java.util.Date utilStartDate = table_Login.getDob();(orwhat ever date your give form obj)
java.sql.Date sqlStartDate = new java.sql.Date(utilStartDate.getTime());(converting date)
Kishan Bheemajiyani
  • 3,429
  • 5
  • 34
  • 68
2

I am a novice: after much running around this worked. Thought might be useful

     String bufDt =  bDOB.getText();  //data from form
     DateFormat dF = new SimpleDateFormat("dd-MM-yyyy"); //data in form is in this format
     Date bbdt = (Date)dF.parse(bufDt);  // string data is converted into java util date
     DateFormat dsF = new SimpleDateFormat("yyyy-MM-dd"); //converted date is reformatted for conversion to sql.date
     String ndt = dsF.format(bbdt); // java util date is converted to compatible java sql date
     java.sql.Date sqlDate=  java.sql.Date.valueOf(ndt);  // finally data from the form is convered to java sql. date for placing in database
PKSawmy
  • 21
  • 1
  • FYI, the terribly troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Dec 31 '18 at 00:37
1

Method for comparing 2 dates (util.date or sql.date)

 public static boolean isSameDay(Date a, Date b) {
    Calendar calA = new GregorianCalendar();
    calA.setTime(a);

    Calendar calB = new GregorianCalendar();
    calB.setTime(b);

    final int yearA = calA.get(Calendar.YEAR);
    final int monthA = calA.get(Calendar.MONTH);
    final int dayA = calA.get(Calendar.DAY_OF_YEAR);

    final int yearB = calB.get(Calendar.YEAR);
    final int monthB = calB.get(Calendar.MONTH);
    final int dayB = calB.get(Calendar.DAY_OF_YEAR);

    return yearA == yearB && monthA == monthB && dayA == dayB;
}
Donovan Thomson
  • 2,375
  • 3
  • 17
  • 25
0

try with this

public static String toMysqlDateStr(Date date) {
    String dateForMySql = "";
    if (date == null) {
        dateForMySql = null;
    } else {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateForMySql = sdf.format(date);
    }

    return dateForMySql;
}
kapil das
  • 2,061
  • 1
  • 28
  • 29
-1

I think the best way to convert is:

static java.sql.Timestamp SQLDateTime(Long utilDate) {
    return new java.sql.Timestamp(utilDate);
}

Date date = new Date();
java.sql.Timestamp dt = SQLDateTime(date.getTime());

If you want to insert the dt variable into an SQL table you can do:

insert into table (expireAt) values ('"+dt+"');
Tom
  • 16,842
  • 17
  • 45
  • 54
  • 1
    This appears to be essentially the same as [this answer](https://stackoverflow.com/a/31237429/1711796) posted a year earlier. – Bernhard Barker Nov 05 '17 at 20:15
-3

i am using the following code please try it out

DateFormat fm= new SimpleDateFormatter();

specify the format of the date you want for example "DD-MM_YYYY" or 'YYYY-mm-dd' then use the java Date datatype as

fm.format("object of java.util.date");

then it will parse your date

tcooc
  • 20,629
  • 3
  • 39
  • 57
UmeshA
  • 11
  • 1
-4

You can use this method to convert util date to sql date,

DateUtilities.convertUtilDateToSql(java.util.Date)
Emmanuel Angelo.R
  • 1,545
  • 2
  • 16
  • 24
  • There's no DateUtilities class in the standard Java library (and I can't even find this method anywhere at all from a quick Google search). If this is from a specific library, you might want to say as much and include a link to the docs. – Bernhard Barker Nov 05 '17 at 20:08
-4

I was trying the following coding that worked fine.

java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate);

abarisone
  • 3,707
  • 11
  • 35
  • 54
PONRAJ
  • 52
  • 9
-8

If you are usgin Mysql a date column can be passed a String representation of this date

so i using the DateFormatter Class to format it and then set it as a String in the sql statement or prepared statement

here is the code illustration:

private String converUtilDateToSqlDate(java.util.Date utilDate) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String sqlDate = sdf.format(utilDate);
    return sqlDate;
}

String date = converUtilDateToSqlDate(otherTransaction.getTransDate());

//then pass this date in you sql statement

  • 14
    Welcome to stackoverflow, I have a few comments to your answer. The question was "how to convert a java.util.Date to java.sql.Date". The code you pasted formats a java.util.Date as yyyy-MM-dd. This is actually of limited use in this context since you should pass the java.sql.Date directly to the jdbc drivers instead of doing it as a string. – jontro Jun 25 '12 at 22:19