Programming: java Date, Calendar, DateFormat

java.util.Date 就是用來表示某個時間點,內部是以一個 long 儲存,而精度是 millisecond 。 jdk 1.0 時,因為未考慮到世界各國時間的差異,所以都是以 Date 這個 class 來表示和處理時間的問題,如可用 year, month, date 來建立一個 Date 物件,或是對某個時間點取出其年月日的資料。但這些資料基本上都是預設以 GMT 為基準。但考慮到世界各國的時區,曆法,和對時間的各種不同的表示法,所以從 jdk1.1 之後,對於時間處理就主要分成 Date, Calendar, DateFormat 三組 class 來處理,並需要配合 Locale 和 TimeZone 。 Date 單純用來表示某一時間點,而 Calendar 用來處理不同的曆法的問題, DateFormat 則處理不同時間的表法,原本 Date 的相關函式就全被標為 deprecated 了。

以 Date 來說, new Date() 就是建立一個表示當下時間的 Date 物件,而另一個可以取當下時間的是 System.currentTimeMillis() ,回傳 long 。而 Date 就大概只剩比較的功能了。

Date 是從 January 1, 1970, 00:00:00 GMT 起算,如果要取某個時間的年月日,先要知道是以什麼曆法來計算。 Java 預設是用 Gregorian 曆,也是一般計算西元的曆法。 Java 用 Calendar 來處理曆法問題, Calendar 是 abstract class ,所以 java 預設也定了 GregorianCalendar 這個 class ,當用 Calendar.getInstance() 時預設就是回傳這個 class (也有其他的曆法,如 http://icu.sourceforge.net/apiref/icu4j/com/ibm/icu/util/ChineseCalendar.htmlhttp://icu.sourceforge.net/apiref/icu4j/com/ibm/icu/util/HebrewCalendar.html 等)。 getInstance() 也可以 Locale 和 TimeZone 當參數傳入,則回傳以不同 TimeZone 為計算基準的 GregorianCalendar (當然日期算法還是相同) 。 基本上 Calendar 的用法就是取得一個 Calendar 的物件,設定給它時間,再取出其對應的年月日。 Calendar 沒有 getYear() 這樣的函式,因為每個不同的曆法就有不同的計算項目 (如農曆有節氣之類的東西,也有什麼子丑寅卯之類的計時方式),所以只有 get() 的函式,而要再傳入要取得的項目,如 get(Calendar.YEAR), get(Calendar.DAY_OF_MONTH) 之類的。(值得注意的是,月份是以 0 起算的,所以 3 是四月)。

        Calendar calendar = Calendar.getInstance();
Date d = new Date();
calendar.setTime(d);
System.out.println("Year: " + calendar.get(Calendar.YEAR));

另一個 Calendar 的用法就是要產生代表某年月日的 Date 物件,用法就是取得 Calendar ,設定年月日資料,再 getTime 取得 Date 。

        Calendar calendar = Calendar.getInstance();
calendar.set(2005, 3, 10, 0, 0, 0);
System.out.println(calendar.getTime());

DateFormat 則是用來處理時間表示法,這個是最複雜的部分。DateFormat 仍然是個 abstract class ,預設我們會用 SimpleDateFormat 這個 class 。簡單的話, DateFormat 就是用來定義某種時間的表示法,可以用來將時間 print 出來,如下用法,

        DateFormat dateformat = new SimpleDateFormat("EEEE-MMMM-dd-yyyy");
Date d = new Date();
System.out.println(dateformat.format(d));

而 DateFormat 和 Calendar, Locale 有關, DateFormat 用 Calendar 來計算要顯示的數字,而用 Locale 來決定要顯示的各種語文不同的表示法,如

        Date d = new Date();
DateFormat dateformat;
dateformat = DateFormat.getDateInstance(DateFormat.FULL, Locale.ENGLISH);
System.out.println(dateformat.format(d));
dateformat = DateFormat.getDateInstance(DateFormat.FULL, Locale.JAPANESE);
System.out.println(dateformat.format(d));
dateformat = DateFormat.getDateInstance(DateFormat.FULL, Locale.CHINESE);
System.out.println(dateformat.format(d));

當然,DateFormat 也可以將文字的時間表示法轉回 Date 物件,但要注意這個動作很容易會有問題 (因為時間格式本來就很複雜):

        Date d;
DateFormat dateformat;
dateformat = new SimpleDateFormat("EEEE-MMMM-dd-yyyy-HH-mm-ss");
d = dateformat.parse("星期二-四月-19-2005-18-25-17");
System.out.println(d);

還有一件很重要的事, DateFormat 不是 Thread Safe 的,所以在 multithread 的情況下不可以在多個 thread 共用同一個 DateFormat 。

另外 java.sql.Date, java.sql.Time, java.sql.Timestamp 也和 Date 有關,基本上這都是 Date ,只是加上和 Datebase 相關的功能,所以程式上的用法也和 Date 相同。

基本上,程式中在設計 API 傳遞時間時,只需要用 java.util.Date 就行了 (如果可能和其他語言如 C 相通的話,不如直接用 long 表示時間),會用到 Calendar 和 DateFormat 只有在輸入輸出時用到。

阅读更多
换一批

没有更多推荐了,返回首页