From Gossip@Openhome

Java Gossip: 使用 Calendar

您可以使用Date來取得完整的日期時間顯示,但如果您想要單獨取得某個時間或日期資訊的話該如何?例如您想知道現在是5月的第幾天?

您要使用Calendar類別,在這之前,您要先知道Calendar的一些方法取回的數字是對應於Calendar本身的常數,也就是說並不是您取回1 這個數字,就表示今天是星期一。

想要取得現在的時間,首先使用Calendar的getInstance()取得一個Calendar的實例,例如:
Calendar rightNow = Calendar.getInstance();
 

如果現在您想知道現在是西元幾年,則可以使用get()方法並指定常數,例如:
System.out.println(rightNow.get(Calendar.YEAR));
 

如果現在是2005年,則上例會顯示2005的數字,依照這個例子,假設撰寫本文的時間是5月份,而您現在想使用程式取得現在的月份,則下例您可能會有些困惑:
System.out.println(rightNow.get(Calendar.MONTH));
 

程式會顯示4這個數字,而不是您預期的5,因為傳回的4並不是代表月份,而是對應於Calendar.MAY常數的值, Calendar在月份上的常數值從Calendar.JANUARY開始是0,到Calendar.DECEMBER的11,所以您如果想要顯示傳回值 的真正意涵,可以如下撰寫:
String[] months = {"一月", "二月", "三月", "四月",
                    "五月", "六月", "七月", "八月",
                    "九月", "十月", "十一月", "十二月"};
       
Calendar rightNow = Calendar.getInstance();
System.out.println(months[rightNow.get(Calendar.MONTH)]);
 

同樣的,如果您想要取得星期資訊,要記得常數從Calendar.SUNDAY是1,到Calendar.SATURDAY是7,由於對應的數並不是從0 開始,所以如果要使用如上的陣列來對應的話,第一個陣列值就不包括資訊,例如:
String[] dayOfWeek = {"", "日", "一", "二",
                           "三", "四", "五", "六"};
       
Calendar rightNow = Calendar.getInstance();
System.out.println(dayOfWeek[
                     rightNow.get(Calendar.DAY_OF_WEEK)]);
 

總之您要記得傳回的值是對應於Calendar的某個常數,會這樣設計的原因在於實際上英文中對於星期或月份並不附以數字上的意涵,如Sunday、 Monday等,幸而除了月份、星期之外,傳回的值都對應於真正的時間意涵,畢竟像西元、小時、分等等本身就是以數字表示。

如果怕搞混,使用switch來比對是個不錯的作法,例如:

  • CalendarDemo.java
package onlyfun.caterpillar;

import java.util.Calendar;

public class CalendarDemo {
public static void main(String[] args) {
Calendar rightNow = Calendar.getInstance();

System.out.println("現在時間是:");
System.out.println("西元:" +
rightNow.get(Calendar.YEAR));
System.out.println("月:" +
getChineseMonth(rightNow));
System.out.println("日:" +
rightNow.get(Calendar.DAY_OF_MONTH));
System.out.println("星期:" +
getChineseDayOfWeek(rightNow));
}

public static String getChineseMonth(Calendar rightNow) {
String chineseMonth = null;

switch(rightNow.get(Calendar.MONTH)) {
case Calendar.JANUARY:
chineseMonth = "一";
break;
case Calendar.FEBRUARY:
chineseMonth = "二";
break;
case Calendar.MARCH:
chineseMonth = "三";
break;
case Calendar.APRIL:
chineseMonth = "四";
break;
case Calendar.MAY:
chineseMonth = "五";
break;
case Calendar.JUNE:
chineseMonth = "六";
break;
case Calendar.JULY:
chineseMonth = "七";
break;
case Calendar.AUGUST:
chineseMonth = "八";
break;
case Calendar.SEPTEMBER:
chineseMonth = "九";
break;
case Calendar.OCTOBER:
chineseMonth = "十";
break;
case Calendar.NOVEMBER:
chineseMonth = "十一";
break;
case Calendar.DECEMBER:
chineseMonth = "十二";
break;
}

return chineseMonth;
}

public static String getChineseDayOfWeek(
Calendar rightNow) {
String chineseDayOfWeek = null;

switch(rightNow.get(Calendar.DAY_OF_WEEK)) {
case Calendar.SUNDAY:
chineseDayOfWeek = "日";
break;
case Calendar.MONDAY:
chineseDayOfWeek = "一";
break;
case Calendar.TUESDAY:
chineseDayOfWeek = "二";
break;
case Calendar.WEDNESDAY:
chineseDayOfWeek = "三";
break;
case Calendar.THURSDAY:
chineseDayOfWeek = "四";
break;
case Calendar.FRIDAY:
chineseDayOfWeek = "五";
break;
case Calendar.SATURDAY:
chineseDayOfWeek = "六";
break;
}

return chineseDayOfWeek;
}
}

在取得一個Calendar的實例後,您可以使用setTime()方法給它一個Date物件,將之改變為Date目前的時間,例如:
Calendar c = Calendar.getInstance();
Date date = new Date(10000000000L);
c.setTime(date);

還可以使用add()方法,來改變Calendar的時間,例如:
c.add(Calendar.MONTH, 1); // 目前時間加1個月
c.add(Calendar.HOUR, 3); // 目前時間加3小時
c.add(Calendar.YEAR, -2); // 目前時間減2年
c.add(Calendar.DAY_OF_WEEK, 3); // 目前的時間加3天

如果打算只針對日期中某個欄位加減,則可以使用roll()方法,例如:
c.roll(Calendar.MONTH, 10); // 只增加月的欄位值為10個月

在上例中,假設是2006/10/1,則執行過後的Calendar實例,其中的時間將是2006/8/1,也就是只改變月份的欄位。