Java Type - 時間型別之間之差異 以PostgreSQL對應
測試平台:JDK SE 6
測試目標:
java.util.Date
java.util.Calendar
java.sql.Date
java.sql.Time
java.sql.Timestamp
測試目的:
對於五種都是所謂的時間類別,有什麼區別。
1.是否能自己產生時間:
java.util.Date:
在java.util.Date建構子上,預設的情況,public Date() { this(System.currentTimeMillis()); } ,預設會調用System.currentTimeMillis()的方法。
System.currentTimeMillis()在API的內容:
currentTimeMillis
public static long currentTimeMillis()
- 返回以毫秒為單位的當前時間。注意,當返回值的時間單位是毫秒時,值的粒度取決於底層作業系統,並且粒度可能更大。例如,許多作業系統以幾十毫秒為單位測量時間。
請參閱
Date
類別的描述,瞭解可能發生在“計算機時間”和協調世界時(UTC)之間的細微差異的討論。 -
- 返回:
- 當前時間與協調世界時 1970 年 1 月 1 日午夜之間的時間差(以毫秒為單位測量)。
- 另請參見:
Date
java.util.Calendar:
java.util.Calendar為抽象類別,建構方式透過Calendar.getInstance()初始, public static Calendar getInstance() { Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault()); cal.sharedZone = true; return cal; } ,在預設的情況下會順便invoked TimeZone.getDefault(),以及Loale.getDefault()這兩個方法。
TimeZone.getDefault()在API的內容:
getDefault
public static TimeZone getDefault()
- 獲取此主機的預設
TimeZone
。預設TimeZone
的來源可能隨實作的變化而變化。 -
- 返回:
- 預設的
TimeZone
。 - 另請參見:
setDefault(java.util.TimeZone)
getDefault
public static Locale getDefault()
- 獲得此 Java 虛擬機器實例的當前預設語言環境值。
Java 虛擬機器根據主機的環境在啟動期間設置預設語言環境。如果沒有明確地指定語言環境,則很多語言環境敏感的方法都使用該方法。可使用
setDefault
方法更改該值。 -
- 返回:
- 此 Java 虛擬機器實例的預設語言環境。
java.sql.Date:
在API的內容:
public class Date
- extends Date
一個套件裝了毫秒值的瘦外覆類別 (thin wrapper),它允許 JDBC 將毫秒值標識為 SQL DATE
值。毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以來經過的毫秒數。
為了與 SQL DATE
的定義一致,由 java.sql.Date
實例包裹的毫秒值必須通過將小時、分鐘、秒和毫秒設置為與該實例相關的特定時區中的零來“規範化”。
可以得知,java.sql.Date屬於一個wrapper class,專門用來承接時間數據,轉為與資料庫中的date型態相符合的型態。
所以java.sql.Date,並無法自己產生出時間。
java.sql.Time:
在API的內容:
public class Time
- extends Date
一個與 java.util.Date
類別有關的瘦外覆類別 (thin wrapper),它允許 JDBC 將該類別標識為 SQL TIME
值。Time
類別添加格式化和解析操作以支持時間值的 JDBC 轉義語法。
應該將日期元件設置為 1970 年 1 月 1 日的 "zero epoch" 值並且不應存取該值。
可以得知,java.sql.Time屬於一個wrapper class,專門用來承接時間數據,轉為與資料庫中的time型態相符合的型態。
所以java.sql.Time,並無法自己產生出時間。
java.sql.Timestamp:
在API的內容:
public class Timestamp
- extends Date
一個與 java.util.Date
類別有關的瘦外覆類別 (thin wrapper),它允許 JDBC API 將該類別標識為 SQL TIMESTAMP
值。它通過允許小數秒到納秒級精度的規範來添加保存 SQL TIMESTAMP
小數秒值的能力。Timestamp 也提供支持時間戳值的 JDBC 轉義語法的格式化和解析操作的能力。
計算 Timestamp 物件的精度為二者之一:
19
,其為 yyyy-mm-dd hh:mm:ss 格式下的字元數20 + s
,其為 yyyy-mm-dd hh:mm:ss.[fff...] 格式下的字元數,s
表示給定 Timestamp 的標度(其小數秒精度)。
註:此型別由 java.util.Date
和單獨的毫微秒值組成。只有整數秒才會存儲在 java.util.Date
元件中。小數秒(毫微秒)是獨立存在的。傳遞不是 java.sql.Timestamp
實例的物件時,Timestamp.equals(Object)
方法永遠不會返回 true
,因為日期的毫微秒元件是未知的。因此,相對於 java.util.Date.equals(Object)
方法而言,Timestamp.equals(Object)
方法是不對稱的。此外,hashcode
方法使用底層 java.util.Date
實作並因此在其計算中不包括毫微秒。
鑒於 Timestamp
類別和上述 java.util.Date
類別之間的不同,建議程式碼一般不要將 Timestamp
值視為 java.util.Date
的實例。Timestamp
和 java.util.Date
之間的繼承關係實際上指的是實作繼承,而不是型別繼承。
可以得知,java.sql.Timestamp屬於一個wrapper class,專門用來承接時間數據,轉為與資料庫中的timestamp型態相符合的型態。所以java.sql.Timestamp,並無法自己產生出時間。
2.對應資料庫存取方法區別:
以下為API內容,選擇java.sql.PreparedStatement內的方法:
setDate
void setDate(int parameterIndex,
Date x)
throws SQLException
- 使用運行應用程序的虛擬機器的預設時區將指定參數設置為給定
java.sql.Date
值。在將此值發送到資料庫時,驅動程序將它轉換成一個 SQLDATE
值。 -
- 參數:
parameterIndex
- 第一個參數是 1,第二個參數是 2,……x
- 參數值- 拋出:
SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;如果發生資料庫存取錯誤,或者在關閉的PreparedStatement
上調用此方法
setTimestamp
void setTimestamp(int parameterIndex,
Timestamp x)
throws SQLException
- 將指定參數設置為給定
java.sql.Timestamp
值。在將此值發送到資料庫時,驅動程序將它轉換成一個 SQLTIMESTAMP
值。 -
- 參數:
parameterIndex
- 第一個參數是 1,第二個參數是 2,……x
- 參數值- 拋出:
SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;如果發生資料庫存取錯誤,或者在關閉的PreparedStatement
上調用此方法
setTime
void setTime(int parameterIndex,
Time x)
throws SQLException
- 將指定參數設置為給定
java.sql.Time
值。在將此值發送到資料庫時,驅動程序將它轉換成一個 SQLTIME
值。 -
- 參數:
parameterIndex
- 第一個參數是 1,第二個參數是 2,……x
- 參數值- 拋出:
SQLException
- 如果 parameterIndex 不對應於 SQL 語句中的參數標記;如果發生資料庫存取錯誤,或者在關閉的PreparedStatement
上調用此方法
由上面三個主要存取給資料庫型別date, time, timestamp 的方法,可以明確了解,在JDBC的要求上,透過java.sql.Date, java.sql.Time, java.sql.Timestamp,最為符合跟資料庫存取的規格,所以java.util.Date, java.util.Calendar,要存進資料庫時,得透過java.sql.Date, java.sql.Time, java.sql.Timestamp 的包覆,才便於存進資料庫。
整理表格如下:
Java Types | 自己產生時間 | 存入PostgreSQL資料庫的對應型別 |
java.util.Date | T | 需要包覆 |
java.util.Calendar | T | 需要包覆 |
java.sql.Date | F | date |
java.sql.Time | F | time |
java.sql.Timestamp | F | timestamp |
沒有留言:
張貼留言