Reputation: 33850
I am trying to save a java.util.Date
from an application to my SQL Server database using JDBC.
When I convert the java.util.Date
to a java.sql.Date
using the method below, it truncates the time part.
java.sql.Date javaSqlExpiryDate = new java.sql.Date(javaUtilExpiryDate.getTime());
System.out.println("javaUtilExpiryDate: " + javaUtilExpiryDate.toString());
System.out.println("javaSqlExpiryDate: " + javaSqlExpiryDate.toString());
The Console window reports the output as:
javaUtilExpiryDate: Thu Sep 01 18:19:08 IST 2016
javaSqlExpiryDate: 2016-09-01
How do I get it to retain the time part as well?
Upvotes: 1
Views: 927
Reputation: 338426
myPreparedObject.setObject(
1 ,
myJavaUtilDate.toInstant() // Convert legacy object to modern java.time object, `Instant`.
)
The other Answers are correct. The java.util.Date
class represents a date and a time-of-day in UTC. The java.sql.Date
represents only a date, without the time-of-day. Well, actually, the java.sql.Date
pretends to represent only a date but actually, as a badly-designed hack, subclasses the java.util.Date
class and therefore does have a time-of-day. Confusing? Yes. One of many reasons to avoid these awful old legacy classes.
Now we have a better way, the java.time classes.
In the old days you would convert your java.util.Date
object to a java.sql.Timestamp
.
Now, with a JDBC driver supporting JDBC 4.2 and later, you can send your java.time objects directly to/from the database. No need for either the java.util nor java.sql classes, just stick with java.time classes.
If you have to interface with old code using java.util.Date
, convert to java.time.Instant
using new methods added to the old classes.
The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = myJavaUtilDate.toInstant() ;
Exchange an Instant
with the database via PreparedStatement::setObject
and ResultSet::getObject
.
myPreparedStatement.setObject( … , instant ) ;
And…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
To see this moment through some other time zone than UTC, apply a ZoneId
to get a ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
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.
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.
Upvotes: 0
Reputation:
Yes, that's the expected and documented behavior.
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.
If you want to keep the time, you need to use java.sql.Timestamp
(especially if the column in the database is defined as datetime
).
Upvotes: 6