杰瑞科技汇

MySQL与Java时间戳如何转换?

Of course! Working with timestamps in MySQL and Java is a common task, but it has several nuances. This guide will cover the best practices, common pitfalls, and code examples.

MySQL与Java时间戳如何转换?-图1
(图片来源网络,侵删)

The Core Concepts

  1. MySQL DATETIME vs. TIMESTAMP:

    • DATETIME: Stores a date and time without timezone information (e.g., '2025-10-27 10:30:00'). It's based on the "wall clock" time of the server. The range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
    • TIMESTAMP: Also stores a date and time, but it's stored in UTC. When you insert a value, MySQL converts it from the server's timezone to UTC. When you retrieve it, MySQL converts it back from UTC to the server's timezone. The range is '1970-01-01 00:00:01' to '2038-01-19 03:14:07'.

    Recommendation: For most applications, especially those that might span multiple timezones, TIMESTAMP is often the better choice because it automatically handles timezone conversion at the database level. However, if your application is strictly tied to a single timezone and you need dates outside the 1970-2038 range, DATETIME is a valid alternative.

  2. Java java.sql.Timestamp vs. java.time (Java 8+):

    • java.sql.Timestamp: This is the "old" JDBC class, designed to match the SQL TIMESTAMP type. It extends java.util.Date but has nanosecond precision. It's legacy and should be avoided in new code.
    • java.time.* (Java 8 and later): This is the modern, standard API for date and time in Java. It's immutable, thread-safe, and much easier to work with. You should always prefer java.time for new applications.

Best Practice: Using java.time with MySQL

This is the recommended approach for modern Java applications.

MySQL与Java时间戳如何转换?-图2
(图片来源网络,侵删)

Step 1: Database Table Setup

Let's create a simple table with a TIMESTAMP column.

CREATE TABLE events (
    id INT AUTO_INCREMENT PRIMARY KEY,
    event_name VARCHAR(100),
    event_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Step 2: Java Code (JDBC with java.time)

You need to use a PreparedStatement to set parameters and ResultSet.getObject() to retrieve them, which correctly maps the SQL TIMESTAMP to a Java java.time.LocalDateTime.

Prerequisites: Make sure you have the MySQL JDBC driver in your project (e.g., in your pom.xml for Maven).

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.33</version> <!-- Use the latest version -->
</dependency>

Java Example Code:

MySQL与Java时间戳如何转换?-图3
(图片来源网络,侵删)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class MySqlJavaTimestampExample {
    // Replace with your database connection details
    private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database";
    private static final String USER = "your_user";
    private static final String PASS = "your_password";
    public static void main(String[] args) {
        // 1. Insert a new event with the current time
        insertEvent("Java Conference");
        // 2. Retrieve and display all events
        getEvents();
    }
    public static void insertEvent(String eventName) {
        String sql = "INSERT INTO events (event_name, event_time) VALUES (?, ?)";
        // Use try-with-resources to ensure the connection is closed
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // Set the event name (String)
            pstmt.setString(1, eventName);
            // Set the event time (LocalDateTime)
            LocalDateTime now = LocalDateTime.now();
            pstmt.setObject(2, now); // The key method: setObject for java.time types
            int affectedRows = pstmt.executeUpdate();
            if (affectedRows > 0) {
                System.out.println("Successfully inserted event: " + eventName + " at " + now);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public static void getEvents() {
        String sql = "SELECT id, event_name, event_time FROM events";
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             PreparedStatement pstmt = conn.prepareStatement(sql);
             ResultSet rs = pstmt.executeQuery()) {
            System.out.println("\n--- List of Events ---");
            while (rs.next()) {
                // Retrieve the event time using getObject, which maps to LocalDateTime
                LocalDateTime eventTime = rs.getObject("event_time", LocalDateTime.class);
                // For display purposes
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                String formattedTime = eventTime.format(formatter);
                System.out.println("ID: " + rs.getInt("id") +
                                   ", Name: " + rs.getString("event_name") +
                                   ", Time: " + formattedTime);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Key Points in the Code:

  • pstmt.setObject(2, now): This is the modern way to set a java.time object as a parameter. JDBC drivers are aware of java.time types and will map them correctly to the SQL TIMESTAMP type.
  • rs.getObject("event_time", LocalDateTime.class): This is the corresponding method for retrieving the value. It tells the JDBC driver to convert the SQL TIMESTAMP into a java.time.LocalDateTime object. You can also use rs.getTimestamp("event_time").toLocalDateTime() for backward compatibility, but getObject is cleaner.
  • No Timezone Handling: Notice that LocalDateTime has no timezone information. This is perfect because we are using MySQL's TIMESTAMP, which handles the conversion to/from UTC automatically. The LocalDateTime you get back from the database is already in your application's default timezone (or the server's timezone).

Advanced: Handling Timezones Explicitly

Sometimes you need more control. If you want to work with a specific timezone or store the raw UTC value, you can use java.time.Instant.

An Instant represents a point on the timeline in UTC, independent of any timezone.

Scenario: Storing and Retrieving UTC Time

Let's modify the table to use DATETIME for this example to show the difference.

CREATE TABLE events_utc (
    id INT AUTO_INCREMENT PRIMARY KEY,
    event_name VARCHAR(100),
    event_time_utc DATETIME -- We will store the raw UTC value here
);

Java Code with Instant:

import java.sql.*;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class MySqlJavaInstantExample {
    // ... (same DB_URL, USER, PASS as before)
    public static void main(String[] args) {
        // Insert an event with the current UTC time
        insertEventUtc("Global Webinar");
        // Retrieve and display, converting to a specific timezone
        getEventsUtc();
    }
    public static void insertEventUtc(String eventName) {
        String sql = "INSERT INTO events_utc (event_name, event_time_utc) VALUES (?, ?)";
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // Get the current moment in UTC
            Instant nowUtc = Instant.now();
            // Set the parameter as an Instant
            pstmt.setObject(2, nowUtc);
            pstmt.setString(1, eventName);
            pstmt.executeUpdate();
            System.out.println("Successfully inserted UTC event: " + eventName + " at " + nowUtc);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public static void getEventsUtc() {
        String sql = "SELECT id, event_name, event_time_utc FROM events_utc";
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             PreparedStatement pstmt = conn.prepareStatement(sql);
             ResultSet rs = pstmt.executeQuery()) {
            System.out.println("\n--- List of UTC Events (converted to US/Eastern) ---");
            ZoneId easternZone = ZoneId.of("America/New_York");
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
            while (rs.next()) {
                // Retrieve the Instant from the DATETIME field
                Instant eventInstant = rs.getObject("event_time_utc", Instant.class);
                // Convert the UTC Instant to a specific timezone
                ZonedDateTime easternTime = eventInstant.atZone(easternZone);
                System.out.println("ID: " + rs.getInt("id") +
                                   ", Name: " + rs.getString("event_name") +
                                   ", UTC Time: " + eventInstant +
                                   ", US/Eastern Time: " + easternTime.format(formatter));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
分享:
扫描分享到社交APP
上一篇
下一篇