我需要能够存储没有时间组件的日期(年/月/日).这是一个日期的抽象概念,例如生日 - 我需要代表一年中的日期而不是特定的时刻.
我使用Java从一些输入文本解析日期,并需要存储在MySQL数据库中.无论数据库,应用程序或任何客户端处于什么时区,他们都应该看到相同的年/月/日.
我的应用程序将在具有与数据库服务器不同的系统时区的计算机上运行,而我无法控制.有没有人有一个优雅的解决方案,以确保我正确存储日期?
我可以想到这些解决方案,这些解决方案看起来都不是很好:
时间
这确实是java.util
日期时间 API 的一个问题,直到 JSR-310 被合并到 Java SE 8 中。该java.util.Date
对象不是像现代日期时间类型那样的真实日期时间对象;相反,它表示自称为“纪元”的标准基准时间January 1, 1970, 00:00:00 GMT
(即(或 UTC))以来的毫秒数。当您打印 的对象时java.util.Date
,其toString
方法会返回 JVM 时区中的日期时间,该日期时间是根据该毫秒值计算得出的。
您描述的问题已通过现代日期时间 API * 解决,其中我们LocalDate
仅表示一个日期。在下面的句子中,Oracle 教程很好地描述了它的用途:
例如,您可以使用 LocalDate 对象来表示出生日期,因为大多数人都在同一天庆祝他们的生日,无论他们是在他们的出生城市还是在国际日期变更线的另一端。
几页后,它再次描述如下:
LocalDate 表示 ISO 日历中的年月日,对于表示没有时间的日期很有用。您可以使用 LocalDate 来跟踪重要事件,例如出生日期或结婚日期。
LocalDate
?它与DATE
ANSI SQL 类型映射。ANSI SQL 类型与java.time
类型的映射在这篇 Oracle 的文章中描述如下:
ANSI SQL | Java SE 8 |
---|---|
日期 | 本地日期 |
时间 | 当地时间 |
时间戳 | 本地日期时间 |
时区时间 | 偏移时间 |
带时区的时间戳 | 偏移日期时间 |
下面给出了将 a 插入LocalDate
到columnfoo
(DATE
类型)的示例代码:
LocalDate localDate = LocalDate.now();
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, localDate);
st.executeUpdate();
st.close();
Run Code Online (Sandbox Code Playgroud)
下面给出了一个LocalDate
从 中检索 a 的示例代码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();
Run Code Online (Sandbox Code Playgroud)
从Trail: Date Time 中了解有关现代日期时间 API * 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和您的 Android API 工作级别仍然不符合 Java-8,请检查通过 desugaring和How to use ThreeTenABP in Android Project可用的 Java 8+ APIs。
我得出的结论是,当前应用程序(直接使用 jdbc 的简单实用程序)中的最佳方法是直接作为字符串插入。对于更大的 Hibernate 应用程序,我可能会费心编写自己的用户类型。不敢相信有人还没有在一些公开可用的代码中解决这个问题......
归档时间: |
|
查看次数: |
3892 次 |
最近记录: |