我正在尝试使用 java.util.Date
作为输入,然后用它创建一个查询 - 所以我需要一个 java.sql.Date
。
我惊讶地发现它不能隐式或显式地进行转换——但我什至不知道该怎么做,因为 Java API 对我来说还是相当新的。
原文由 David Ackerman 发布,翻译遵循 CC BY-SA 4.0 许可协议
我正在尝试使用 java.util.Date
作为输入,然后用它创建一个查询 - 所以我需要一个 java.sql.Date
。
我惊讶地发现它不能隐式或显式地进行转换——但我什至不知道该怎么做,因为 Java API 对我来说还是相当新的。
原文由 David Ackerman 发布,翻译遵循 CC BY-SA 4.0 许可协议
没关系….
public class MainClass {
public static void main(String[] args) {
java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
System.out.println("utilDate:" + utilDate);
System.out.println("sqlDate:" + sqlDate);
}
}
原文由 David Ackerman 发布,翻译遵循 CC BY-SA 2.5 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
1 回答2.4k 阅读✓ 已解决
tl;博士
不。
Date
两个类都已过时。 Sun 、 Oracle 和 JCP 社区几年前就放弃了这些遗留的日期时间类,一致采用了定义 java.time 类的 JSR 310 。java.util.Date
&java.sql.Date
与 JDBC 4.2 或更高版本。遗产现代的转换
java.util.Date
java.time.Instant
java.util.Date.toInstant()
java.util.Date.from( Instant )
java.sql.Date
java.time.LocalDate
java.sql.Date.toLocalDate()
java.sql.Date.valueOf( LocalDate )
使用
PreparedStatement
的示例查询。替代品:
Instant
而不是java.util.Date
两者都代表 UTC 中的一个时刻。但现在用纳秒而不是毫秒。 -
LocalDate
而不是java.sql.Date
两者都表示没有时间和时区的仅日期值。
细节
如果您尝试使用仅日期值(无时间、无时区),请使用
LocalDate
类而不是java.util.Date
。java.time
在 Java 8 及更高版本中,与早期版本的 Java 捆绑在一起的麻烦的旧日期时间类已被新的 java.time 包 取代。请参阅 Oracle 教程。大部分功能已在 ThreeTen- Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中 进一步适应 Android。
SQL 数据类型
DATE
意味着只有日期,没有时间和时区。在 Java 8 中的java.time.LocalDate
之前,Java 从未有过这样的类†。让我们通过根据特定时区获取今天的日期来创建这样的值(时区对于确定日期很重要,因为新的一天更早黎明例如,在巴黎比在蒙特利尔)。至此,我们可能就完成了。如果您的 JDBC 驱动程序 符合 JDBC 4.2 规范,您应该能够将
LocalDate
通过setObject
在PreparedStatement
上传递到存储到 SQLATE 字段中。同样,使用
ResultSet::getObject
从 SQL DATE 列获取到 JavaLocalDate
对象。在第二个参数中指定类使您的代码 类型安全。换句话说, 这整个问题在 JDBC 4.2 或更高版本下是无关紧要的。
如果您的 JDBC 驱动程序不以这种方式执行,您需要退回到转换为 java.sql 类型。
转换为 java.sql.Date
要进行转换,请使用添加到旧日期时间类的新方法。我们可以调用
java.sql.Date.valueOf(…)
来转换一个LocalDate
。并走向另一个方向。
从
java.util.Date
转换虽然您应该避免使用旧的日期时间类,但在使用现有代码时可能会被迫这样做。如果是这样,您可以转换为/从 java.time。
通过
Instant
类,它代表 UTC 时间线上的时刻。一个Instant
在思想上类似于一个java.util.Date
。但请注意,Instant
的分辨率高达 纳秒,而java.util.Date
只有 毫秒 的分辨率。要进行转换,请使用添加到旧类的新方法。例如,
java.util.Date.from( Instant )
和java.util.Date::toInstant
。要确定日期,我们需要时区的上下文。对于任何给定的时刻,日期在全球范围内因时区而异。应用
ZoneId
以获得ZonedDateTime
。† java.sql.Date 类假装只有日期,没有时间,但 实际上 是时间,调整为午夜时间。令人困惑?是的,旧的日期时间课程一团糟。
关于 java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的 旧 日期时间类,例如
java.util.Date
、Calendar
和SimpleDateFormat
。要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是 JSR 310 。
现在处于 维护模式 的 Joda-Time 项目建议迁移到 java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要
java.sql.*
类。 Hibernate 5 & JPA 2.2 支持 java.time 。从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如
Interval
、YearWeek
、YearQuarter
等等。