在MySQL数据库表中,有一列名为loginTime,其类型为timestamp。它的值为2023-02-14 10:02:26.
当我使用 java 获取日期类型变量的值时,我得到的值为 2023-02-14 10:02。我怎样才能得到有秒数的日期。和数据库一样。我试过了,但仍然找不到解决方案。
正确的现代解决方案:
myResultSet.getObject( … , OffsetDateTime.class ) // Returns an `java.time.OffsetDateTime` object.
你说:
名为 loginTime 的列,其类型为时间戳。它的值为 2023-02-14 10:02:26。
不,你错了。
TIMESTAMP
类型表示具有 UTC 时间的日期。您报告的值缺少与 UTC 零偏移的指示,这是重要信息。
接受的答案在三个方面是不明智的:
LocalDateTime
班级。 LocalDateTime
是这里使用的错误类。 MySQL 中的 TIMESTAMP
数据类型是 UTC 中的日期和时间。 LocalDateTime
缺少任何 offset 的概念,因此该解决方案可悲地丢弃了有价值的信息。注意前面Ole V.V.的评论第一步是阅读 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
。
您很可能需要包含时间戳类,它允许 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();
}
}
}
此变体未经测试