If I use java.util.Date
's toInstant()
on a variable which happens to be a java.sql.Date
, I get an UnsupportedOperationException
.
try {
java.util.Date input = new java.sql.Date(System.currentTimeMillis());
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
} catch (UnsupportedOperationException e) {
// grrr!
}
The java.util.Date
that I'm concerned with comes from a DATE field in a mysql DB via a legacy API, and is actually a java.sql.Date
.
Now the following related questions are all very interesting:
UnsupportedOperationException - Why can't you call toInstant() on a java.sql.Date?
Convert java.util.Date to java.time.LocalDate
LocalDate to java.util.Date and vice versa simplest conversion?
but they don't provide any elegant way of truncating a java.util.Date
to get rid of the time component and get a Java 8 LocalDate
.
I admit there is an issue that the same instant in time in one timezone might be a different date from the same instant in another timezone.
I suspect the solution will involve java.util.Calendar but rather than craft my own solution I'd rather establish what others have done first.
I'd prefer to find something shorter than this:
from Resetting the time part of a timestamp in Java :
Date date = new Date(); // timestamp now Calendar cal = Calendar.getInstance(); // get calendar instance cal.setTime(date); // set cal to date cal.set(Calendar.HOUR_OF_DAY, 0); // set hour to midnight cal.set(Calendar.MINUTE, 0); // set minute in hour cal.set(Calendar.SECOND, 0); // set second in minute cal.set(Calendar.MILLISECOND, 0); // set millis in second Date zeroedDate = cal.getTime(); // actually computes the new Date
Often the simplest solutions are the hardest to find:
public LocalDate convertDateObject(java.util.Date suspectDate) {
try {
// Don't do this if there is the smallest chance
// it could be a java.sql.Date!
return suspectDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
} catch (UnsupportedOperationException e) {
// BOOM!!
}
// do this first:
java.util.Date safeDate = new Date(suspectDate.getTime());
return safeDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}