2013-10-16 26 views
-2

我發現沒有辦法將日期/時間插入到標準區域(如UTC中)的MySQL數據庫中。將特定區域的日期/時間插入到MySQL數據庫中

以下代碼段使用Apache DBCP對用戶進行身份驗證。

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_login的類型爲DATETIME


我想插入日期/時間在MySQL中沒有發生的UTC區。它似乎需要一個本地區域。

通過任何方式,是否可以在UTC區插入日期/時間到MySQL中? Java和/或MySQL中的任何數據類型都可能被建議 - 不僅僅是我在這裏介紹的。

回答

0

Date是Java中時區不可知的。它始終以UTC(默認和始終)。因此,DateTimestamp本身不是原因,但是當Date/Timestamp通過JDBC驅動程序傳遞到數據庫時,它將依據JVM時區依次解釋日期/時間(默認爲系統時區)(本機操作系統區)。

因此,除非明確強制MySQL JDBC驅動程序使用UTC區域或JVM本身設置爲使用該區域,否則即使配置了MySQL本身,它也不會使用UTC將Date/Timestamp存儲到目標數據庫中使用default_time_zone='+00:00'my.inimy.cnf[mysqld]部分中使用UTC。有些數據庫如Oracle可能支持帶時區的時間戳,也可能是我不熟悉的一個例外(未經測試,因爲我目前沒有該環境)。

void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException

使用給定日曆對象中的指定參數設置爲給定值java.sql.Timestamp, 。驅動程序使用日曆對象 構造一個SQL TIMESTAMP值,然後驅動程序將該值發送到 數據庫。使用Calendar對象時,驅動程序可以計算考慮到自定義時區的 時間戳。 如果沒有指定Calendar對象 ,則驅動程序使用默認時區,即運行應用程序的虛擬機的默認時區爲 。

同樣的事情還提到了其他相關的getter和setter方法處理日期,時間在java.sql.PreparedStatement類。

這可以通過檢查MySQL JDBC驅動程序實現的setTimestampInternal()方法的調用來進一步闡明。

請參閱以下two調用方法的兩個重載版本中的setTimestampInternal()方法。

/** 
* Set a parameter to a java.sql.Timestamp value. The driver converts this 
* to a SQL TIMESTAMP value when it sends it to the database. 
* 
* @param parameterIndex the first parameter is 1... 
* @param x the parameter value 
* 
* @throws SQLException if a database access error occurs 
*/ 
public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { 
    setTimestampInternal(parameterIndex, x, this.connection.getDefaultTimeZone()); 
} 

/** 
* Set a parameter to a java.sql.Timestamp value. The driver converts this 
* to a SQL TIMESTAMP value when it sends it to the database. 
* 
* @param parameterIndex the first parameter is 1, the second is 2, ... 
* @param x the parameter value 
* @param cal the calendar specifying the timezone to use 
* 
* @throws SQLException if a database-access error occurs. 
*/ 
public void setTimestamp(int parameterIndex, java.sql.Timestamp x,Calendar cal) throws SQLException { 
    setTimestampInternal(parameterIndex, x, cal.getTimeZone()); 
} 

因此,當與PreparedStatement#setTimestamp()方法沒有指定Calendar例如,默認時區將被使用(this.connection.getDefaultTimeZone())或與所提供的Calendar實例中指定時區將被使用(cal.getTimeZone()) 。

因此,只需將java.util.Calendar或其子類java.util.GregorianCalendar的實例傳遞給您感興趣的合適時區(我們感興趣的UTC)的PreparedStatement#setTimestamp()

Timestamp timestamp = new Timestamp(new java.util.Date().getTime()); 
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 

preparedStatement.setTimestamp(1, timestamp, calendar); 

指定的時區將被用於生成Timestamp的字符串表示它傳遞到底層數據庫之前被提供。


如果你碰巧對付像Hibernate,EclipseLink的一個ORM框架,使用適當的數據源中的應用服務器/ Servlet容器創建一個連接池沿,然後參考this answer這個答案是基於並且是直接複製而來。

1

您可以在兩個地方爲您的mySQL數據設置時區:全局配置和會話配置。你不能指定爲mysql'這個日期是GMT,但這個日期是EST'。你必須將它們轉換爲共同的時區。

最佳做法是將您的服務器設置爲特定的時區[例如:GMT],並​​確保您在存儲過程中相應地轉換日期/時間。實際上,所有後端數據都應該使用單個時區,並且任何轉換都應該在輸出之前立即進行。

相關問題