杰瑞科技汇

SQL Date转Java Date如何正确转换?

  1. 传统方式:使用 java.util.Date
  2. 现代推荐方式:使用 Java 8+ 的 java.time API

概览:SQL 与 Java 日期类型对应关系

了解 SQL 和 Java 中常见的日期/时间类型及其对应关系非常重要。

SQL Date转Java Date如何正确转换?-图1
(图片来源网络,侵删)
SQL 类型 (JDBC java.sql 包) Java 8+ 类型 (java.time 包) 描述
java.sql.Date java.sql.Date (已过时) 仅存储日期(年-月-日),无时间部分,对应 SQL DATE
java.sql.Time java.sql.Time (已过时) 仅存储时间(时-分-秒),无日期部分,对应 SQL TIME
java.sql.Timestamp java.time.LocalDateTime 存储日期和时间,纳秒级精度,对应 SQL TIMESTAMPDATETIME
java.sql.Timestamp java.time.Instant 存储一个时间点,基于 UTC 时区,对应 SQL TIMESTAMP

传统方式 - 使用 java.util.Date

java.util.Date 是 Java 最早引入的日期时间类,但它设计上有很多缺陷(它同时包含日期和时间,但方法如 getDate(), getMonth() 已被废弃,且时区处理混乱),尽管不推荐在新代码中使用,但在维护旧项目时你一定会遇到。

java.sql.Date 转换到 java.util.Date

java.sql.Datejava.util.Date 的子类,所以转换非常直接。

import java.sql.Date;
import java.util.Date;
public class SqlDateToUtilDate {
    public static void main(String[] args) {
        // 假设这是从数据库中获取的 java.sql.Date 对象
        // PreparedStatement.getDate("birth_date")
        java.sql.Date sqlDate = Date.valueOf("2025-10-27"); // 使用 valueOf 从字符串创建
        // 直接赋值,因为 java.sql.Date 是 java.util.Date 的子类
        java.util.Date utilDate = sqlDate;
        System.out.println("java.sql.Date: " + sqlDate);
        System.out.println("java.util.Date: " + utilDate);
        // 注意:打印时,utilDate 会显示时间部分(通常是 00:00:00)
        // 因为 java.util.Date 总是包含日期和时间
    }
}

java.sql.Timestamp 转换到 java.util.Date

java.sql.Timestamp 也是 java.util.Date 的子类,所以转换同样直接。

import java.sql.Timestamp;
import java.util.Date;
public class SqlTimestampToUtilDate {
    public static void main(String[] args) {
        // 假设这是从数据库中获取的 java.sql.Timestamp 对象
        // PreparedStatement.getTimestamp("create_time")
        java.sql.Timestamp sqlTimestamp = Timestamp.valueOf("2025-10-27 10:30:45.123456789");
        // 直接赋值
        java.util.Date utilDate = sqlTimestamp;
        System.out.println("java.sql.Timestamp: " + sqlTimestamp);
        System.out.println("java.util.Date: " + utilDate);
        // 注意:utilDate 会丢失纳秒级的精度,因为它只精确到毫秒
    }
}

现代推荐方式 - 使用 Java 8+ 的 java.time API

自 Java 8 起,官方引入了 java.time 包,它提供了更清晰、更安全、功能更强大的日期时间 API。**强烈建议在所有新项目中使用,`

SQL Date转Java Date如何正确转换?-图2
(图片来源网络,侵删)

java.sql.Date 转换

java.sql.Date 提供了 toLocalDate() 方法,可以轻松地转换为 java.time.LocalDate

import java.sql.Date;
import java.time.LocalDate;
public class SqlDateToLocalDate {
    public static void main(String[] args) {
        java.sql.Date sqlDate = Date.valueOf("2025-10-27");
        // 1. 转换为 java.time.LocalDate (最常用)
        LocalDate localDate = sqlDate.toLocalDate();
        System.out.println("java.sql.Date: " + sqlDate);
        System.out.println("java.time.LocalDate: " + localDate); // 格式: 2025-10-27
        // 如果需要从 LocalDate 再转回 java.sql.Date (存回数据库)
        java.sql.Date sqlDateAgain = Date.valueOf(localDate);
        System.out.println("转换回 java.sql.Date: " + sqlDateAgain);
    }
}

java.sql.Timestamp 转换

java.sql.Timestamp 提供了多个转换方法,非常方便。

import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class SqlTimestampToJavaTime {
    public static void main(String[] args) {
        java.sql.Timestamp sqlTimestamp = Timestamp.valueOf("2025-10-27 10:30:45.123456789");
        // 1. 转换为 java.time.LocalDateTime (推荐,无时区信息)
        // 这保留了日期和时间,但不带时区信息。
        LocalDateTime localDateTime = sqlTimestamp.toLocalDateTime();
        System.out.println("java.sql.Timestamp: " + sqlTimestamp);
        System.out.println("java.time.LocalDateTime: " + localDateTime); // 格式: 2025-10-27T10:30:45.123456789
        // 2. 转换为 java.time.Instant (推荐,表示一个时间点)
        // Instant 基于UTC,非常适合用于记录事件或序列化。
        Instant instant = sqlTimestamp.toInstant();
        System.out.println("java.time.Instant: " + instant); // 格式: 2025-10-27T10:30:45.123Z
        // 3. 转换为 java.time.ZonedDateTime (带有时区信息)
        // 如果需要将时间与特定时区关联,可以使用这个。
        ZoneId defaultZoneId = ZoneId.systemDefault(); // 获取系统默认时区
        ZonedDateTime zonedDateTime = instant.atZone(defaultZoneId);
        System.out.println("java.time.ZonedDateTime: " + zonedDateTime); // 格式: 2025-10-27T18:30:45.123+08:00[Asia/Shanghai] (假设在中国)
    }
}

总结与最佳实践

转换场景 传统方式 (java.util.Date) 现代推荐方式 (java.time)
SQL DATE -> Java java.sql.Date -> java.util.Date (直接赋值) java.sql.Date -> java.time.LocalDate (.toLocalDate())
SQL TIMESTAMP -> Java java.sql.Timestamp -> java.util.Date (直接赋值) java.sql.Timestamp -> java.time.LocalDateTime (.toLocalDateTime()) 或 java.time.Instant (.toInstant())
Java -> SQL DATE java.util.Date -> java.sql.Date (构造函数) java.time.LocalDate -> java.sql.Date (.valueOf())
Java -> SQL TIMESTAMP java.util.Date -> java.sql.Timestamp (构造函数) java.time.Instant -> java.sql.Timestamp (.from(Instant))

核心建议:

  1. 拥抱 java.time:在所有新的 Java 项目中,优先使用 java.time 包下的类,它们是不可变的,线程安全,API 设计得非常直观。
  2. 理解 LocalDateTime vs Instant
    • 当你关心的是“本地”的日历和时间(用户的生日、会议安排),使用 LocalDateTime
    • 当你关心的是全球统一的一个“时间点”(日志记录、数据库事件时间戳),使用 Instant
  3. 数据库驱动层:现代的 JDBC 驱动通常也支持直接从 ResultSet 中获取 java.time 类型的对象,getLocalDate(), getLocalDateTime(), getInstant() 等,如果可能,直接使用这些方法,可以避免先获取 java.sql 类型再转换的麻烦。
分享:
扫描分享到社交APP
上一篇
下一篇