java.time
This was indeed a problem with java.util
date-time API until JSR-310 was incorporated in Java SE 8. The java.util.Date
object is not a real date-time object like the modern date-time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT
(or UTC). When you print an object of java.util.Date
, its toString
method returns the date-time in the JVM's timezone, calculated from this milliseconds value.
The problem that you have described was addressed with the modern date-time API* where we have LocalDate
that represents just a date. In the following sentence, the Oracle tutorial describes its purpose nicely:
For example, you might use a LocalDate object to represent a birth
date, because most people observe their birthday on the same day,
whether they are in their birth city or across the globe on the other
side of the international date line.
A couple of pages later, it describes it again as follows:
A LocalDate represents a year-month-day in the ISO calendar and is
useful for representing a date without a time. You might use a
LocalDate to track a significant event, such as a birth date or
wedding date.
Which datatype should I use for LocalDate
?
It maps with DATE
ANSI SQL type. The mapping of ANSI SQL types with java.time
types have been depicted as follows in this Oracle's article:
ANSI SQL |
Java SE 8 |
DATE |
LocalDate |
TIME |
LocalTime |
TIMESTAMP |
LocalDateTime |
TIME WITH TIMEZONE |
OffsetTime |
TIMESTAMP WITH TIMEZONE |
OffsetDateTime |
How to use it in JDBC?
Given below is a sample code to insert a LocalDate
into columnfoo
(which is of DATE
type):
LocalDate localDate = LocalDate.now();
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, localDate);
st.executeUpdate();
st.close();
Given below is a sample code to retrieve a LocalDate
from columnfoo
:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
// Assuming the column index of columnfoo is 1
LocalDate localDate = rs.getObject(1, LocalDate.class));
System.out.println(localDate);
}
rs.close();
st.close();
Learn more about the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.