gpt4 book ai didi

Java 没有将准确的日期存储到 mysql 数据库

转载 作者:行者123 更新时间:2023-11-29 06:37:40 37 4
gpt4 key购买 nike

我正在编写一个程序,将字符串转换为 java.util.Date 对象,然后将其存储在数据库中,该程序运行正确,没有错误。但是在MySql中,日期存储不正确,java存储的日期是相对于字符串中写入的日期的昨天日期。示例-如果我写“2018-11-10”,它会存储“2018-11-09”。我的代码-

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Demo {

public static void main(String[] args) throws ClassNotFoundException, SQLException {
Connection con;
Class.forName("com.mysql.cj.jdbc.Driver");
Date date = Date.valueOf("2018-11-20");
con = DriverManager.getConnection("jdbc:mysql://localhost:9090/ProjectScheduler", "root", "tiger");
PreparedStatement prepare = con.prepareStatement("insert into SchedulerDB(Date) values(?)");
prepare.setDate(1, date);
prepare.executeUpdate();
}
}

在 MySql 工作台中,我将表创建为

create table SchedulerDB(Date date)

当我运行选择查询以使用

查看表中的数据时
select * from SchedulerDB

然后在表“SchedulerDB”中的“日期”列下,我得到了 2018-11-19。但我想要 2018-11-20,因为这是我用 java 代码编写的。请帮我解决这个问题。

最佳答案

tl;博士

myPreparedStatement.setObject(
… ,
LocalDate.parse( "2018-11-20")
) ;

详细信息

您正在使用设计糟糕的java.sql.Date类。不幸的是,这个类是 java.util.Date 的子类,尽管文档奇怪地告诉我们忽略继承的事实。因此,虽然java.sql.Date假装仅表示日期,但它实际上是一个时刻,是某个区域中时间设置为午夜的日期然后调整为UTC。这是一个糟糕的设计,也是从不使用遗留日期时间类的众多原因之一。

对于 SQL 中的 DATE 列,请使用现代的 LocalDate 类。

本地日期

LocalDate类真正代表仅日期值,没有日期时间,也没有 time zoneoffset-from-UTC .

对于类似于 SQL 标准 DATE 类型的数据库列,请使用 Java 中的 LocalDate 类。

LocalDate ld = LocalDate.parse( "2018-11-20" );

JDBC 4.2

从 JDBC 4.2 开始,我们可以直接与数据库交换 java.time 对象。

myPreparedStatement.setObject( … , ld ) ;

检索:

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

如果不涉及时区,您检索到的值将与您存储的 2018-11-20 相同。

示例应用

这是一个使用 H2 Database Engine 的完整示例应用程序。作为演示,我将其设置为写入内存数据库,而不是持久保存到实际存储。

我们创建一个包含单个表和两列的数据库:

  • 名为 pkey_ 的连续数字主键
  • 名为 when_DATE

我们插入几个 LocalDate 对象,然后检索行以转储到控制台。

package com.basilbourque.example;

import java.sql.*;
import java.time.LocalDate;
import java.util.List;

public class EventDate {
public static void main ( String[] args ) {
EventDate app = new EventDate();
app.doIt();
}

private void doIt ( ) {
final String driverName = "org.h2.Driver";
final String catalogName = "event_demo_db";
final String jdbcPath = "jdbc:h2:mem:" + catalogName + ";DB_CLOSE_DELAY=-1"; // Set delay to keep in-memory database even after last connection closed.

// Verify JDBC driver.
try {
Class.forName( driverName );
} catch ( ClassNotFoundException e ) {
e.printStackTrace();
}

// Connect, and create database.
try (
Connection conn = DriverManager.getConnection( jdbcPath ) ;
) {
String sql = null;

// Create table.
try ( Statement stmt = conn.createStatement() ; ) {
sql = "CREATE TABLE " + "event_" + " ( \n" +
" pkey_ IDENTITY PRIMARY KEY , \n" +
" when_ DATE NOT NULL \n" +
") ; \n";
System.out.println( "TRACE - SQL:\n" + sql );
stmt.execute( sql );
}
System.out.println( "TRACE - Created table `event_`." );

// Add rows
sql = "INSERT INTO event_ ( when_ ) \n" +
"VALUES ( ? ) " +
"; ";

List < LocalDate > dates = List.of( LocalDate.parse( "2018-11-10" ) , LocalDate.parse( "2018-12-31" ) );
System.out.println( "Inserting list of LocalDate objects: " + dates );
try (
PreparedStatement ps = conn.prepareStatement( sql ) ;
) {
for ( LocalDate localDate : dates ) {
ps.setObject( 1 , localDate );
ps.executeUpdate();
}
}

// Retrieve rows
sql = "SELECT * FROM " + "event_" + " ;";
try (
Statement stmt = conn.createStatement() ;
ResultSet rs = stmt.executeQuery( sql ) ;
) {
while ( rs.next() ) {
int pkey = rs.getInt( "pkey_" );
LocalDate when = rs.getObject( "when_" , LocalDate.class );
System.out.println( "Row pkey_: " + pkey + " when_: " + when );
}
}


} catch ( SQLException e ) {
e.printStackTrace();
}

}
}

运行时。

Inserting list of LocalDate objects: [2018-11-10, 2018-12-31]

Row pkey_: 1 when_: 2018-11-10

Row pkey_: 2 when_: 2018-12-31


关于java.time

java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧类 legacy日期时间类,例如 java.util.Date , Calendar , & SimpleDateFormat .

Joda-Time项目,现在位于 maintenance mode ,建议迁移到java.time类。

要了解更多信息,请参阅 Oracle Tutorial 。并在 Stack Overflow 上搜索许多示例和解释。规范为JSR 310 .

您可以直接与数据库交换java.time对象。使用JDBC driver符合JDBC 4.2或稍后。不需要字符串,不需要 java.sql.* 类。

从哪里获取java.time类?

ThreeTen-Extra项目通过附加类扩展了 java.time。该项目是 java.time future 可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 Interval , YearWeek , YearQuarter ,和 more .

关于Java 没有将准确的日期存储到 mysql 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53090564/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com