从数据库中获取时间戳值,就像使用 java 一样

问题描述 投票:0回答:2

在MySQL数据库表中,有一列名为loginTime,其类型为timestamp。它的值为2023-02-14 10:02:26.

当我使用 java 获取日期类型变量的值时,我得到的值为 2023-02-14 10:02。我怎样才能得到有秒数的日期。和数据库一样。我试过了,但仍然找不到解决方案。

java mysql date timestamp datetime-format
2个回答
2
投票

tl;博士

正确的现代解决方案:

myResultSet.getObject( … , OffsetDateTime.class )  // Returns an `java.time.OffsetDateTime` object.

你说:

名为 loginTime 的列,其类型为时间戳。它的值为 2023-02-14 10:02:26。

不,你错了。

TIMESTAMP
类型表示具有 UTC 时间的日期。您报告的值缺少与 UTC 零偏移的指示,这是重要信息。

详情

接受的答案在三个方面是不明智的:

  • 第一部分使用存在严重缺陷的遗留日期时间类,这些类在多年前被 JSR 310. 中定义的现代 java.time
  • 类所取代
  • 第二部分使用
    LocalDateTime
    班级。
    LocalDateTime
    是这里使用的错误类。 MySQL 中的
    TIMESTAMP
    数据类型是 UTC 中的日期和时间。
    LocalDateTime
    缺少任何 offset 的概念,因此该解决方案可悲地丢弃了有价值的信息。注意前面Ole V.V.的评论
  • 这两部分都专注于解析从数据库中检索到的文本。相反,应该将日期时间列值检索到 Java 中的日期时间类型中。无需诉诸文字。

第一步是阅读 MySQL 8.0 中 TIMESTAMP

 数据类型的文档
。引用:

TIMESTAMP 数据类型用于包含日期和时间部分的值。 TIMESTAMP 的范围是“1970-01-01 00:00:01”UTC 到“2038-01-19 03:14:07”UTC。

那些提到“UTC”的是至关重要的。该术语是一个缩写,意思是“与 UTC 时间子午线的偏移量为零时分秒”。

SQL标准中,这种类型等同于

TIMESTAMP WITH TIME ZONE
(标准作者错误地使用了术语“时区”,他们的意思是“偏移量”)。

java.time.OffsetDateTime

因此在JDBC规范中映射到此类列的适当Java类型是

OffsetDateTime

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

要写入这样的值,请将您的

OffsetDateTime
对象传递给
PreparedStatement#setObject


0
投票

您很可能需要包含时间戳类,它允许 JDBC API 将 java.util.Date 对象识别为 SQL TIMESTAMP 值。在这里,我们设置一个时间戳值以包括小数秒并显示:

// old classes and approach in use here, read on for more 
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

public class TimestampExample {
    public static void main(String[] args) {
        try {
            String timestampStr = "2023-02-14 10:02:26.123";
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
            Timestamp loginTime = new Timestamp(dateFormat.parse(timestampStr).getTime());
            System.out.println("loginTime: " + loginTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

已添加:这是使用 Java.time 的替代方法(请参阅答案下的评论)

// don't use this approach if the source data has embedded time zone information 
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class TimestampExample {
    public static void main(String[] args) {
        try {
            String timestampStr = "2023-02-14 10:02:26.123";
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
            LocalDateTime loginTime = LocalDateTime.parse(timestampStr, formatter);
            System.out.println("loginTime: " + loginTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

从来没有打算专注于将日期/时间信息作为文本处理,上面的代码片段只是为了轻松可视化亚秒精度而设计的。根据评论中不断涌现的建议,我假设以下内容将更正确地处理 MySQL“时间戳”。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.time.OffsetDateTime;

public class TimestampExample {
    public static void main(String[] args) {
        try {
            // Assume the connection has been established

            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT login_time FROM users WHERE id = 1");

            if (rs.next()) {
                OffsetDateTime loginTime = rs.getObject("login_time", OffsetDateTime.class);
                System.out.println("loginTime: " + loginTime);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

此变体未经测试

© www.soinside.com 2019 - 2024. All rights reserved.