从ResultSet中获取日期时间(java)

16

我在 MySql 数据库中有两列存储了 DateTime 值,

当我尝试在 Java 中从 ResultSet 中获取它们时,没有 getDateTime() 选项:

我应该使用 getDate() 吗?或者这样行得通吗?

先感谢您。

6个回答

21

只使用getDate()仅返回一个Date,因此在您的情况下,如果您想要日期和时间,请使用getTimestamp(String columnLabel)。这应该有效,并将String columnLabel替换为数据库中实际列名称。


3
“getTimestamp”是“Timestamp”,但是该字段是“DateTime”,这导致编译错误。 - Saiteja Parsi
时间戳 ts1 = rs.getTimestamp(String columnLabel); DateTime dt1 = new DateTime(ts1); 如果需要更改时区,请检查您的时间。 DateTime dt1 = new DateTime(ts1, DateTimeZone.UTC); - StuckOnSimpleThings

4

4

在MySQL中优先使用timestamp而不是datetime

首先,如果您的数据库中的datetime表示一个时间点,请使用MySQL中的timestamp数据类型,而不是datetimedatetime可以被解释成任何读者或程序所使用的时区,这可能会导致难以调试的错误。不同的关系型数据库管理系统对于timestamp数据类型的行为也不相同。在MySQL中,timestamp确保日期和时间处于UTC时区,因此避免了对其他时区的错误解释。这更加安全。如果将日期和时间存储在数据库中对于您所在时区的用户来说有些困难,也值得这样做。

java.time

    PreparedStatement ps = yourDatabaseConnection.prepareStatement("select your_datetime_col from your_table;");
    try (ResultSet rs = ps.executeQuery()) {
        while (rs.next()) {
            OffsetDateTime dateTime = rs.getObject("your_datetime_col", OffsetDateTime.class);
            // do something with dateTime
        }
    }

使用ResultSet.getObject()从数据库中检索日期和时间,并将其转换为来自现代Java日期和时间API的类型。在问题和其他答案中提到或隐含的类java.sql.Timestampjava.sql.Datejava.util.Date设计不佳且已过时,因此我建议改用现代API。它需要一个符合JDBC 4.2标准的驱动程序。大多数人都有这个,MySQL也有一个很多年的版本,所以我认为你应该没有问题。

如果您无法更改MySQL中的数据类型,请使用LocalDateTime在Java中检索datatime列的值。它的使用方式与上面的代码相同。

回答您具体的问题

我应该使用getDate()吗?那样可行吗?

不行。 getDate()只会给您一个包含数据库中日期部分的java.sql.Date,其中缺少时间部分。正如我所说,java.sql.Date也设计不佳,是对已经设计不佳的java.util.Date的真正hack,因此您应该根本不想要它。

链接


1
java.sql.Timestamp 转换为 java.util.Date
java.util.Date date = rs.getDate(index_position); // O/P: DD:MM:YYYY

java.sql.Timestamp timestamp = rs.getTimestamp(index_position); // O/P: DD:MM:YYYY HH:mm:ss
java.util.Date date = new java.util.Date(timestamp.getTime());

如果您将时间戳转换为java.sql.Timestamp,则结果为DD:MM:YYYY 00:00:00,因为日期不包括时间。因此,它选择默认值00:00:00
SQL TimeStamp  : 30.12.2020 13.40.50
Java TimeStamp : 30.12.2020 13.40.50

SQL TimeStamp  : 30.12.2020 13.40.50
Java Date      : 30.12.2020 00.00.00
Java TimeStamp : 30.12.2020 00.00.00

根据ResultSetMetaData获取CSV报告的记录示例:

public static void getTestTable(Connection con) throws SQLException {
    String sql = "select ID, INSERTDATE, TO_CHAR(INSERTTIME,'DD.MM.YYYY HH24:MI:SS') as String_Time, INSERTTIME, MSG from TEST_TABLE group by ID, INSERTDATE, INSERTTIME, MSG";
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery(sql);
    if (rs != null) {
        ResultSetMetaData resultSetMetaData = rs.getMetaData();
        int noOfColumns = resultSetMetaData.getColumnCount(); // For iteration
        System.out.println("No of Cloumns Query Returns: "+ noOfColumns);
        HashMap<String, ArrayList<?>> matrixTable = getMatrixMetadata(resultSetMetaData);
        System.out.println("MatrixTable: "+matrixTable);
        ArrayList<String> dataTypeList = (ArrayList<String>) matrixTable.get("ColumnTypeName");
        int rowCount = 0;
        while (rs.next()) { // CSV Report
            for (int columnIndex = 1; columnIndex <= noOfColumns; columnIndex++) {
                // int id = rs.getInt("ID");
                String value = getMatrixValue(rs, dataTypeList, columnIndex);
                System.out.print(value);
                if (columnIndex < noOfColumns) {
                    System.out.print(",");
                }
            }
            System.out.println();
            rowCount++;
        }
        System.out.println("Result FetchSize(Total Coloumns):"+rs.getFetchSize()+" = Rows*Coloums:["+rowCount+"*"+noOfColumns+"]"); 
    }
}
static HashMap<String, ArrayList<?>> getMatrixMetadata(ResultSetMetaData meta) throws SQLException {
    int columnsCount = meta.getColumnCount();
    ArrayList<String> columnList = new ArrayList<String>();
    ArrayList<String> dataTypeNameList = new ArrayList<String>();
    ArrayList<Integer> dataTypeIdList = new ArrayList<Integer>();
    HashMap<String, ArrayList<?>> returnHashMap = new HashMap<String, ArrayList<?>>();
    for (int i = 1; i <= columnsCount; i++) {
        columnList.add(meta.getColumnName(i));
        dataTypeIdList.add(Integer.valueOf(meta.getColumnType(i)));
        dataTypeNameList.add(meta.getColumnTypeName(i));
    }
    returnHashMap.put("ColumnName", columnList);
    returnHashMap.put("ColumnTypeId", dataTypeIdList);
    returnHashMap.put("ColumnTypeName", dataTypeNameList);
    return returnHashMap;
}
static DecimalFormat DECIMAL_FORMAT = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
static { // https://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html
    DECIMAL_FORMAT.applyPattern("######.###"); // "#,#00.0#" → 1,234.56 
}
public static String getMatrixValue(ResultSet rs, ArrayList<String> dataTypeNameList, int pos) throws SQLException {
    String retval;
    String columnTypeName = dataTypeNameList.get(pos - 1);
    //int type = dataTypeIdList.get(pos - 1);
    //if (type == Types.DECIMAL || type == Types.DOUBLE || type == Types.FLOAT || type == Types.NUMERIC || type == Types.REAL) {
    if (columnTypeName.equalsIgnoreCase("NUMBER")) {
        double doubleValue = rs.getDouble(pos);
        if (rs.wasNull()) {
            retval = null;
        } else {
            retval = "[N]"+DECIMAL_FORMAT.format(doubleValue);
        }
    } else if (columnTypeName.equalsIgnoreCase("DATE")) {
        java.util.Date date = rs.getDate(pos);
        if (rs.wasNull()) { // Checks last column read had a value of SQL NULL.
            retval = null;
        } else {
            retval = "[D]"+formatDate(date, "dd.MM.yy");
        }
    } else if (columnTypeName.equalsIgnoreCase("TIMESTAMP")) {
        java.sql.Timestamp timestamp = rs.getTimestamp(pos);
        if (rs.wasNull()) {
            retval = null;
        } else {
            java.util.Date date = new java.util.Date(timestamp.getTime());
            retval = "[T]"+formatDate(date, "dd.MM.yyyy HH:mm");
        }
    } else { // VARCHAR2
        retval = "[S]"+rs.getString(pos);
    }
    return retval;
}
public static String formatDate(Date aDate, String formatStr) {
    DateFormat dateFormat = new SimpleDateFormat( formatStr );
    //dateFormat.setCalendar(Calendar.getInstance(TimeZone.getTimeZone("IST")));
    return dateFormat.format(aDate);
}

No of Cloumns Query Returns: 5
MatrixTable: {ColumnName=[ID, INSERTDATE, STRING_TIME, INSERTTIME, MSG], ColumnTypeId=[2, 93, 12, 93, 12], ColumnTypeName=[NUMBER, DATE, VARCHAR2, TIMESTAMP, VARCHAR2]}
[N]1,[D]30.12.20,[S]30.12.2020 00:40:50,[T]30.12.2020 00:40,[S]Insert1
[N]2,[D]30.12.20,[S]30.12.2020 13:40:50,[T]30.12.2020 13:40,[S]Insert2
Result FetchSize(Total Coloumns):10 = Rows*Coloums:[2*5]

SQL查询涉及表的创建和多记录插入:Oracle Multi insert
CREATE TABLE SCHEMA7.TEST_TABLE ( "ID" NUMBER, "INSERTDATE" DATE, "INSERTTIME" TIMESTAMP (6), "MSG" VARCHAR2(120 BYTE) );

INSERT INTO SCHEMA7.TEST_TABLE  (ID, INSERTDATE, INSERTTIME, MSG) VALUES ('1', TO_DATE('30-DEC-2020', 'DD-MON-RR'), TO_TIMESTAMP('30-DEC-2020 12.40.50.00 AM', 'DD-MON-RR HH.MI.SS.FF AM'), 'Insert1');
INSERT INTO SCHEMA7.TEST_TABLE  (ID, INSERTDATE, INSERTTIME, MSG) VALUES ('2', TO_DATE('30.12.2020', 'DD.MM.YYYY'), TO_TIMESTAMP('30.12.2020 13.40.50','dd.mm.yyyy hh24.mi.ss'), 'Insert2');

1

或者使用从日期到字符串的类型转换:

resultSet.getDate(1).toString());

将返回:

2014-02-18

数据库字段数据:"2014-02-18 00:00:00.000"


1
getDate() 不会返回 time 部分。如果想要 mysql datetimetime 部分,这并不是最好的选择。 - veer7

0

我正在使用这个:

public static Date getDate(ResultSet rs, int col, Date def)
{
    try
    {
        Timestamp ts = rs.getTimestamp(col, Calendar.getInstance());
        if(!rs.wasNull())
        {
            return  new Date(ts.toInstant().toEpochMilli());
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return def;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接