杰瑞科技汇

MySQL与Java的datetime类型如何转换?

Of course! Working with java.time (the modern Java date/time API) and DATETIME in MySQL is a very common task. The key is to understand how to convert between them correctly.

MySQL与Java的datetime类型如何转换?-图1
(图片来源网络,侵删)

Here’s a comprehensive guide covering the best practices, common pitfalls, and complete code examples.

The Core Concept: java.time.Instant vs. java.time.LocalDateTime

This is the most important distinction to understand:

  • java.time.LocalDateTime: Represents a date and time without a time zone (e.g., "2025-10-27 10:30:00"). It's a "local" view, tied to the system's clock default.
  • java.time.Instant: Represents a specific moment on the timeline in UTC (e.g., "2025-10-27T10:30:00Z"). It's an "absolute" point in time, independent of any time zone.
  • MySQL DATETIME: A data type that stores a date and time. Crucially, it has no time zone information. It just stores the numbers. When you store a DATETIME, you are implicitly storing it in the time zone of the MySQL server or the connection session.

The Golden Rule:

  • Use java.time.LocalDateTime when you want to represent a "wall-clock" time that is tied to a specific geographic location (e.g., "The meeting is at 2 PM in New York").
  • Use java.time.Instant when you want to represent an absolute point in time that is the same everywhere (e.g., "The server processed the request at 2025-10-27T14:30:00Z").

For most applications, especially those dealing with user-facing data, java.time.LocalDateTime is the most intuitive choice to map to MySQL DATETIME, as it avoids confusion with time zones.

MySQL与Java的datetime类型如何转换?-图2
(图片来源网络,侵删)

Method 1: The Recommended Modern Approach (using JDBC 4.2+)

If you are using Java 8+ and a modern JDBC driver (version 8.0.16+ for MySQL Connector/J), you can pass java.time objects directly to PreparedStatement and get them from ResultSet. This is the cleanest and safest method.

Setting a DATETIME from Java to MySQL

You use PreparedStatement.setObject().

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.LocalDateTime;
public class MysqlJavaDatetimeSet {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/your_database";
        String user = "your_user";
        String password = "your_password";
        String sql = "INSERT INTO events (event_name, event_time) VALUES (?, ?)";
        try (Connection conn = DriverManager.getConnection(url, user, password);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // 1. Create a Java LocalDateTime object
            LocalDateTime eventTime = LocalDateTime.of(2025, 10, 27, 15, 30, 0);
            // 2. Set parameters using setObject
            pstmt.setString(1, "Product Launch");
            pstmt.setObject(2, eventTime); // The magic happens here!
            int affectedRows = pstmt.executeUpdate();
            System.out.println(affectedRows + " row(s) inserted.");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Getting a DATETIME from MySQL to Java

You use ResultSet.getObject().

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDateTime;
public class MysqlJavaDatetimeGet {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/your_database";
        String user = "your_user";
        String password = "your_password";
        String sql = "SELECT event_name, event_time FROM events WHERE id = 1";
        try (Connection conn = DriverManager.getConnection(url, user, password);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            if (rs.next()) {
                // 1. Get the value using getObject, specifying the target type
                LocalDateTime eventTime = rs.getObject("event_time", LocalDateTime.class);
                String eventName = rs.getString("event_name");
                System.out.println("Event Name: " + eventName);
                System.out.println("Event Time: " + eventTime); // Automatically formatted
                System.out.println("Event Time (custom format): " + eventTime.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Method 2: The Legacy Approach (using java.util.Date and java.sql.Timestamp)

Before Java 8, this was the standard way. It still works but is less type-safe and more error-prone.

  • java.util.Date: Represents an instant in time with millisecond precision.
  • java.sql.Timestamp: A subclass of java.util.Date that adds nanosecond precision. It's the specific type JDBC uses for DATETIME and TIMESTAMP.

Setting a DATETIME from Java to MySQL

You must convert java.util.Date to java.sql.Timestamp.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
public class MysqlJavaLegacySet {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/your_database";
        String user = "your_user";
        String password = "your_password";
        String sql = "INSERT INTO events_legacy (event_name, event_time) VALUES (?, ?)";
        try (Connection conn = DriverManager.getConnection(url, user, password);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // 1. Create a java.util.Date object
            Date utilDate = new Date(); // Current moment
            // 2. Convert it to a java.sql.Timestamp
            Timestamp sqlTimestamp = new Timestamp(utilDate.getTime());
            // 3. Set the parameter
            pstmt.setString(1, "Legacy Event");
            pstmt.setTimestamp(2, sqlTimestamp);
            int affectedRows = pstmt.executeUpdate();
            System.out.println(affectedRows + " row(s) inserted.");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Getting a DATETIME from MySQL to Java

You get a java.sql.Timestamp from the ResultSet and can convert it to java.util.Date if needed.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Date;
public class MysqlJavaLegacyGet {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/your_database";
        String user = "your_user";
        String password = "your_password";
        String sql = "SELECT event_name, event_time FROM events_legacy WHERE id = 1";
        try (Connection conn = DriverManager.getConnection(url, user, password);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            if (rs.next()) {
                // 1. Get the value as a Timestamp
                Timestamp timestamp = rs.getTimestamp("event_time");
                Date utilDate = rs.getDate("event_time"); // Can also get as java.sql.Date
                String eventName = rs.getString("event_name");
                System.out.println("Event Name: " + eventName);
                System.out.println("Event Time (as Timestamp): " + timestamp);
                System.out.println("Event Time (as Date): " + utilDate);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Important: Handling Time Zones

This is where most mistakes happen.

Problem: You create a LocalDateTime in your application (e.g., 15:30 in New York) and store it directly. The MySQL server is in UTC. When you retrieve it, it will still be 15:30, but it's now 15:30 UTC, which is a completely different moment in time.

Solution 1 (Recommended): Store Everything in UTC

The best practice for any serious application is to store all timestamps in UTC.

  1. On the Java side: Get the user's local time, convert it to an Instant (UTC), and store that.
  2. On the MySQL side: Use the TIMESTAMP data type, which is stored in UTC and converted to the server's time zone for display.
  3. When retrieving: Get the TIMESTAMP as an Instant or ZonedDateTime in UTC, then convert it to the user's local time for display.

Example: Storing in UTC

import java.sql.*;
import java.time.*;
import java.time.ZoneId;
// ... (Connection setup) ...
// 1. User's local time
ZonedDateTime localTime = ZonedDateTime.of(2025, 10, 27, 15, 30, 0, 0, ZoneId.of("America/New_York"));
System.out.println("User's local time: " +
分享:
扫描分享到社交APP
上一篇
下一篇