Java 将特定区域中的日期/时间插入MySQL数据库
我找不到在UTC这样的标准区域将日期/时间插入MySQL数据库的方法 下面的代码段使用ApacheDBCP对用户进行身份验证Java 将特定区域中的日期/时间插入MySQL数据库,java,mysql,jdbc,timezone,utc,Java,Mysql,Jdbc,Timezone,Utc,我找不到在UTC这样的标准区域将日期/时间插入MySQL数据库的方法 下面的代码段使用ApacheDBCP对用户进行身份验证 public final class AuthenticationDAO { public boolean isAuthenticated(String userName, String password) throws SQLException { Connection connection = null; PreparedSt
public final class AuthenticationDAO {
public boolean isAuthenticated(String userName, String password) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
boolean status = false;
try {
connection = DatabaseConnection.getConnection();
preparedStatement = connection.prepareStatement("select * from admin_tbl where lower(admin_id)=lower(?) and BINARY password=?");
preparedStatement.setString(1, userName);
preparedStatement.setString(2, password);
resultSet = preparedStatement.executeQuery();
status = resultSet.next();
if (status) {
preparedStatement = connection.prepareStatement("update admin_tbl set last_login=? where lower(admin_id)=lower(?) and BINARY password=?");
preparedStatement.setTimestamp(1, new Timestamp(new Date().getTime())); // java.util.Date / java.sql.Timestamp
preparedStatement.setString(2, userName);
preparedStatement.setString(3, password);
preparedStatement.executeUpdate();
}
} finally {
if (connection != null) {connection.close();}
if (resultSet != null) {resultSet.close();}
if (preparedStatement != null) {preparedStatement.close();}
}
return status;
}
}
只有一行代码是我们感兴趣的
preparedStatement.setTimestamp(1, new Timestamp(new Date().getTime()));
当用户/管理员成功登录时,此行更新登录日期/时间。MySQL中的last\u login
列的类型为DATETIME
我想在MySQL的UTC区域中插入没有发生的日期/时间。它似乎需要一个局部区域
无论如何,是否可以在UTC区域的MySQL中插入日期/时间?Java和/或MySQL中的任何数据类型都可能会被推荐——不仅仅是我在这里介绍的数据类型。您可以在两个位置设置MySQL数据的时区:全局配置和会话配置。您不能向mysql指定“此日期为GMT,但此日期为EST”。您必须将它们转换为一个公共时区
最佳做法是将服务器设置为特定时区[例如:GMT],并确保在存储期间相应地转换日期/时间。实际上,所有后端数据都应该使用一个时区,任何转换都应该在输出之前立即进行。
Date
在Java中与时区无关。它始终采用UTC(默认情况下,始终如此)。因此,Date
或Timestamp
本身不是原因,但当Date
/Timestamp
通过JDBC驱动程序传递到数据库时,它会根据JVM时区解释日期/时间,而JVM时区又默认为系统时区(本机操作系统时区)
因此,除非MySQL JDBC驱动程序被明确强制使用UTC区域,或者JVM本身被设置为使用该区域,它不会使用UTC将日期
/时间戳
存储到目标数据库中,即使MySQL本身被配置为使用[mysqld]
部分中的my.ini
或my.cnf
中的默认时区='+00:00'
使用UTC。有些数据库(如Oracle)可能支持带时区的时间戳,这可能是我不熟悉的一个例外(未测试,因为我目前没有该环境)
将指定参数设置为给定的java.sql.Timestamp
值,
使用给定的日历对象。驱动程序使用日历对象
构造一个SQL时间戳
值,然后驱动程序将其发送到
数据库。使用日历对象,驱动程序可以计算
考虑自定义时区的时间戳如果没有日历
对象
指定时,驱动程序使用默认时区,即
运行应用程序的虚拟机
在java.sql.PreparedStatement
类中处理日期时间的其他相关getter和setter方法也提到了同样的事情
这可以通过检查MySQL JDBC驱动程序实现的方法调用来进一步澄清
请参阅从setTimestamp()
方法的两个重载版本中调用setTimestamp()
方法
/**
*将参数设置为java.sql.Timestamp值。驱动程序将此转换为
*在将SQL时间戳值发送到数据库时,将其转换为SQL时间戳值。
*
*@param parameterIndex第一个参数是1。。。
*@param x参数值
*
*@在发生数据库访问错误时引发SQLException
*/
public void setTimestamp(int参数索引,Timestamp x)引发SQLException{
setTimestampInternal(parameterIndex,x,this.connection.getDefaultTimeZone());
}
/**
*将参数设置为java.sql.Timestamp值。驱动程序将此转换为
*在将SQL时间戳值发送到数据库时,将其转换为SQL时间戳值。
*
*@param parameterIndex第一个参数是1,第二个参数是2。。。
*@param x参数值
*@param cal指定要使用的时区的日历
*
*如果发生数据库访问错误,@将引发SQLException。
*/
public void setTimestamp(int-parameterIndex,java.sql.Timestamp x,Calendar-cal)引发SQLException{
setTimestampInternal(parameterIndex,x,cal.getTimeZone());
}
因此,当使用PreparedStatement#setTimestamp()
方法未指定任何Calendar
实例时,将使用默认时区(this.connection.getDefaultTimeZone()
)或使用提供的Calendar
实例的指定时区(cal.getTimeZone()
)
因此,只需将java.util.Calendar
或其子类java.util.Gregoriacalendar
的一个实例传递给PreparedStatement\setTimestamp()
,并带有您感兴趣的适当时区(我们感兴趣的UTC)
Timestamp Timestamp=new Timestamp(new java.util.Date().getTime());
日历日历=Calendar.getInstance(TimeZone.getTimeZone(“UTC”);
preparedStatement.setTimestamp(1,时间戳,日历);
指定的时区将用于生成所提供的时间戳
的字符串表示形式,然后再将其传递给基础数据库
如果您碰巧处理了一个ORM框架,比如Hibernate,EclipseLink以及使用适当的数据源在应用服务器/Servlet容器中创建一个连接池,那么请参考这个答案所基于并直接从中复制的