有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用JDBC写回MySQL数据时毫秒值之间的差异

我用new java.sql.Date(0)调用JDBC setDate

我执行JDBCgetDate并调用java.sql.Date.getTime()。它返回-19800000(这是历元,但表示为相对于我的时区的毫秒数)

我处理的是毫秒,因为这是REST Api中接收到的

我使用的是MySql日期列和MySql连接器5.1

编辑:添加一些代码来总结问题

//SQL INSERT INTO DATE_TEST(STARTDATE) VALUES(?);
//Setting the date
ps.setDate(1, new java.sql.Date(0));
ps.executeUpdate();

//SQL SELECT STARTDATE FROM DATE_TEST
Date entryDate = rs.getDate(1);
Long lEntryDate = entryDate.getTime();
//Now lEntryDate is -19800000

知道为什么会这样吗

  • 是因为该列是日期列吗
  • 是因为它将输入视为UTC,并假设输出是相对于当前时区所必需的吗

编辑2: 我添加了更完整的代码,重现了这个问题

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

public class DateMySqlTest {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/hdb", "root", "");

            //Insert
            PreparedStatement ps = con.prepareStatement("INSERT INTO DATE_TEST(DATEFIELD) VALUES(?)");
            java.sql.Date inDate = new java.sql.Date(0);
            System.out.println("Write milliseconds: " + inDate.getTime());
            ps.setDate(1, inDate);
            ps.executeUpdate();

            //Read
            Statement stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT DATEFIELD FROM DATE_TEST");
            while (rs.next()){
                java.sql.Date outDate = rs.getDate(1);
                System.out.println("Read milliseconds: " + outDate.getTime());
            }

            con.close();
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }

    }
}

控制台输出:

Write milliseconds: 0
Read milliseconds: -19800000

共 (1) 个答案

  1. # 1 楼答案

    您的困惑源于这样一个事实:您正在使用setDategetDate而没有可选的Calendar参数,因此这些方法正在解释本地时区(IST,UTC+5:30)中的日期/时间值。具体来说

    • new java.sql.Date(0)生成日期/时间值1970-01-01 00:00:00 UTC,该值setDate解释为1970-01-01 05:30:00 IST

    • 当MySQL将值保存到DATE列时,它会截断时间部分,因此得到1970-01-01。没关系

    • 但是,当您检索时,值getDate(1)将日期/时间值解释为1970-01-01 00:00:00 IST,即纪元之前的1969-12-31 18:30:00 UTC或19800000ms

    为了避免这个问题,你可以使用

    Date entryDate = rs.getDate(1, Calendar.getInstance(TimeZone.getTimeZone("UTC")));
    

    这将把1970-01-01解释为1970-01-01 00:00:00 UTC,如你所愿