先看一個簡單的圖:
主要的類有:
Date類負責時間的表示,在計算機中,時間的表示是一個較大的概念,現有的系統基本都是利用從1970.1.1 00:00:00 到當前時間的毫秒數進行計時,這個時間稱為epoch。在后文中如果沒有明確說明,毫秒數就是指從1970年到對應時間的毫秒數。在Java 的Date類內部其實也是一個毫秒數,對外表現為一個Date對象。
Calendar是一個工具類,負責對Date類進行修改等操作,以及從Date類中提取年月日等時間的特定信息。
DateFormat 則負責日期的轉換,比如讀取特定格式的字符串,轉換成date對象,或者將date對象按照指定的格式轉成字符串。
1 Date 表示時刻。內部主要是一個long值存儲距離紀元時的毫秒數。絕大多數方法都是過時的。
這里指的是:java.util.Date 日期格式:年月日時分秒
public class Date{ private transient long fastTime; Date(){ this(System.currentTimeMillis()); } Date(long date){ fastTime = date; } //…… }
2 TimeZone 時區(24個,如Asia/shanghai)
//獲取默認時區 TimeZone.getDefault();
3 Locale 國家(或地區)和語言(如zh_CN)
// 獲取默認國家和語言 Locale.getDefault();
4 Calendar 是日期和時間操作的主要類,是抽象類,提供了多個靜態方法,可以獲取Calendar實例。
與Date類似,Calendar內部也有一個表示時刻的毫秒數,還定義了一個數組(長度17),表示日歷中各個字段的值。
proteted long time; proteted int fields[];
fields中存放的是下面這些字段的值,給Calendar
Calendar.YEAR,
Calendar.MONTH,
Calendar.DAY_OF_MONTH,
Calendar.DAY_OF_WEEK,
Calendar.HOUR_OF_DAY,
Calendar.MINUTE,
Calendar.SECOND,
Calendar.MILLISECOND
可以通過Calendar實例獲取這些值(Calendar會根據時區,地區語言進行轉換)。
//空構造函數,會獲取當前的。 Calendar.getInstance("Asia/shanghai","zh_CN") Calendar calendar = Calendar.getInstance(); int day = calendar.get(Calendar.DAY_OF_MONTH);
Calendar還支持根據字段增加減少時間(負數表示減少)。
Calendar.getInstance().add(Calendar.MONTH,-2);
總結來說,Calendar做了一項非常繁瑣的工作,根據TimeZone 和 Locale 再絕對時間毫秒數和日歷字段之間自動進行轉換。
5 DateFormat(線程不安全) 提供Date和字符串表示之間的轉換,主要的兩個方法 format(Date d),parse(String s)
Date的字符串表示與TimeZone、Locale都是相關的。
同時與兩個格式化風格相關,一個是日期格式化風格,一個是時間格式化風格。
DataFormat是抽象方法,也用工廠方法創建對象。
DateFormat.getTimeInstance();
DateFormat.getDateInstance();
DateFormat.getDateTimeInstance();
其中getTimeInstance只處理時間,getDateInstance只處理日期,getDateTimeInstance處理日期和時間,三種對象的處理結果如下
Calendar calendar = Calendar.getInstance(); //結果是21:34:20 DateFormat.getTimeInstance().format(calendar.getTime()); //結果是2019-02-20 DateFormat.getDateInstance().format(calendar.getTime()); //結果是2019-02-20 21:34:20 DateFormat.getDateTimeInstance().format(calendar.getTime());
DateFormat雖然比較方便,但是日期字符串格式的更精確的控制,則應該使用SimpleDateFormat。
6 SimpleDateFormat(線程不安全) 是DateFormat的子類,與父類主要不同是:子類可以自定義日期格式。
String pattern = "yyyy年MM月dd日 E HH時mm分ss秒"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); //輸出結果是 2019年02月20日 Wed 21時44分42秒 OS.print(simpleDateFormat.format(calendar.getTime()));
pattern 中的英文字符a-z,A-Z表示特殊含義,其他字符原樣輸出.
pattern變量參數 | 對應的實際意義 | 示例 |
---|---|---|
yyyy | 4位的年份 | 2019 |
MM | 月份兩位數 | 02 |
dd | 日期 | 20 |
HH/hh | 24小時制/12小時制 | 21/09 |
mm | 分鍾 | 55 |
ss | 秒 | 55 |
E | 星期幾 | wed |
a | 上午下午,一般配合hh使用 | PM |
SimpleDateFormat也可以方便的將字符串轉成Date。
String str = "19年2月20日 09時58分33秒111"; Date date = new SimpleDateFormat("yy年M月dd日 HH時mm分ss秒SSS").parse(str); //結果 2019年02月20日 09時58分33秒 String result = new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒").format(date);
7.java.sql.Date繼承於java.util.Date,只保留了日期
java.sql.Date
類在JDBC API
中被使用,日期格式:年月日。如果你需要在java.sql.PreparedStatement
上設置日期或者從java.sql.ResultSet
獲取日期,你將會和java.sql.Date
打交道。
你可以用java.util.Date
做的任何事同樣適用於java.sql.Date。
long time = System.currentTimeMillis(); java.sql.Date date = new java.sql.Date(time);
java.sql.Date
和java.util.Date
最大的不同在於java.sql.Date
所表示的日期中只保留了日期,而沒有時間。
舉個例子,如果你用2009-12-24 23:20來創建一個java.sql.Date
,那么其中的時間(23:20)將會被切掉。如果你需要保留時間,使用 java.sql.Timestamp
來代替java.sql.Date
。
8.java.sql.Time繼承於java.util.Date,只保留了時間
同java.sql.Date
類在JDBC API
中被使用,日期格式:時分秒。
9.java.sql.Timestamp繼承於java.util.Date,
對java.util.Date 類進行了擴充,該類提供了 getNanos() 方法
同java.sql.Date
類在JDBC API
中被使用,日期格式:年月日時分秒納秒。
10.TimeUnit是一個時間單位枚舉類,主要用於並發編程
時間單元表示給定粒度單元的時間持續時間,並提供實用程序方法來跨單元轉換,以及在這些單元中執行計時和延遲操作。時間單元不維護時間信息,但只幫助組織和使用可能在不同上下文中分別維護的時間表示。
例如:嘗試獲取鎖50毫秒:
Lock lock = ...; if (lock.tryLock(50L, TimeUnit.MILLISECONDS)) ...
參考:https://www.jianshu.com/p/1478af429a1e
https://blog.csdn.net/zhao123h/article/details/53012791
http://ifeve.com/java-sql-date/