I have the following scenario:
Calendar
objectDateTime
object that I use to do heavy
One problem may be that java.sql.Date are supposed to be…
'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.
…according to the documentation. That means, the time portion of the date-time is being cleared from your java.util.Date or Joda-Time DateTime objects.
As the correct answer by Gilbert Le Blanc notes, both java.util.Date and java.sql.Date have no concept of time zone internally. They store the number of milliseconds since the Unix epoch.
Those classes pull a nasty trick: Their toString
methods apply your JVM's default time zone to the rendering of the string. Very confusing. The Date
object has no time zone, yet when displayed as a string you see a time zone.
If your java.util.Date object contains the number of 1344902399000L milliseconds since the epoch (1970 start), that means 2012-08-13T23:59:59.000Z
in UTC/GMT. But if your JVM believes itself to be in France with Daylight Saving Time (DST) in effect, you'll see 2 hours ahead of UTC/GMT: 2012-08-14T01:59:59.000+02:00
described in that class' awful string format. The same moment of time has different day-of-month meaning (13 vs 14) in different time zones, with the clock-on-the-wall being past midnight.
The Joda-Time 2.4 library can be helpful here. Pass either the java.sql.Date or java.util.Date object to a DateTime constructor along with the UTC time zone object to get a clear picture of the value with which you are struggling.
java.util.Date date = new java.util.Date( 1390276603054L );
DateTime dateTimeUtc = new DateTime( date, DateTimeZone.UTC );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
When run…
2014-01-21T03:56:43.054Z
To convert the other direction from Joda-Time to java.util.Date…
java.util.Date date = myDateTime.toDate();
To convert the other direction from Joda-Time to java.sql.Date…
java.sql.Date date = new java.sql.Date( myDateTime.getMillis() );
The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
The equivalent of java.util.Date
is Instant
. 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 = Instant.ofEpochMilli( 1390276603054L );
Apply a time zone, ZoneId
, to produce a ZonedDateTime
which is akin to a java.util.Calendar
and a Joda-Time DateTime
.
ZoneId z = ZoneId.of( "Europe/Kaliningrad" );
ZonedDateTime zdt = instant.atZone( z );
Now extract a date-only value, the date portion of that ZonedDateTime
, as a LocalDate
. The LocalDate class represents a date-only value without time-of-day and without time zone. So LocalDate
is what java.sql.Date
is pretending to be: a date-only value.
LocalDate localDate = zdt.toLocalDate() ;
In JDBC 4.2 and later, you can use the java.time types directly with a compliant driver via PreparedStatement::setObject
and ResultSet::getObject
.
myPreparedStatement.setObject( … , localDate );
…and…
LocalDate ld = myResultSet.getObject( … , LocalDate.class );
For an older non-compliant driver, convert briefly to a java.sql.Date
object to/from a LocalDate
by using new methods added to the old class: toLocalDate
and valueOf( LocalDate )
.