java.util.Date
vs java.sql.Date
Your output looks to be coming from a java.util.Date
rather than a java.sql.Date
.
It is unfortunately easy to mixup the two. Besides the Date
name, the sql
one technically is a subclass of the other util
one. Beware: This is a hack, and a bad hack at that. The documentation warns us to pretend the two are not in an inheritance relationship. But the compiler does not know that.
Here is some example code showing these two classes and the different behavior of their respective toString
method.
// Legacy classes
System.out.println( "java.sql.Date: " + new java.sql.Date( Instant.now().toEpochMilli() ) ) ;
System.out.println( "java.util.Date: " + new java.util.Date() ) ;
See this code run live at IdeOne.com.
java.sql.Date: 2018-07-31
java.util.Date: Tue Jul 31 22:44:14 GMT 2018
You can see the java.sql.Date::toString
method uses the shorter YYYY-MM-DD format used in SQL environments. That format also happens to comply with ISO 8601 standard as well, by the way.
In contrast, the output you report matches that of java.util.Date::toString
.
java.time
The issue is moot. You are using terrible old date-time classes that were supplanted years ago by the java.time classes.
java.sql.Date
is replaced by java.time.LocalDate
, a date-only only value without a time-of-day and without a time zone. (FYI, java.sql.Date
pretends to have no time-of-day or time zone but actually has both, as an awkward subclass of java.util.Date
.)
java.util.Date
is replaced by java.time.Instant
. Both represent a moment in UTC, though Instant
has a finer resolution of nanoseconds instead of milliseconds. (FYI, java.util.Date
actually has a time zone buried deep, inaccessible without getter/setter methods, but used in equals
etc. One of many poor design decisions in these legacy classes.)
Here is some code, counterparts to that seen above.
// Modern classes
System.out.println( "LocalDate.now(): " + LocalDate.now() ;
System.out.println( "Instant.now(): " + Instant.now() ) ;
System.out.println( "ZonedDateTime.now( … ): " + ZonedDateTime.now( ZoneId.of( "Africa/Tunis" ) ) ) ;
See this code run live at IdeOne.com.
LocalDate.now(): 2018-07-31
Instant.now(): 2018-07-31T22:57:27.763Z
ZonedDateTime.now( … ): 2018-07-31T23:57:27.904+01:00[Africa/Tunis]
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
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
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.