java.time时间
直到JSR-310被纳入Java SE 8之前,这确实是java.util
日期时间API的一个问题。 java.util.Date
对象不像现代日期时间类型那样是真正的日期时间对象。相反,它表示自“纪元”以来的毫秒数,即 1970年1月1日00:00:00 GMT
(或UTC)的标准基准时间。当您打印java.util.Date
对象时,它的toString
方法返回JVM的时区中的日期时间,从这个毫秒值计算得出。
您所描述的问题已经得到使用现代日期-时间API*解决,其中我们拥有表示日期的LocalDate
。在下文中,Oracle教程很好地描述了它的目的:
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 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
?
它与DATE
ANSI SQL类型进行映射。在此Oracle文章中,已经将ANSI SQL类型与java.time
类型的映射描述如下:
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?
以下是一个示例代码,用于将 LocalDate
插入 columnfoo
(它是 DATE
类型):
LocalDate localDate = LocalDate.now();
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, localDate);
st.executeUpdate();
st.close();
下面是一个示例代码,用于从columnfoo
中检索LocalDate
:
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();
从 Trail: Date Time 了解关于 现代日期时间 API* 的更多信息。
* 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.