Calendar類


接觸java不久,感覺java真的挺好玩的。

Calendar 類是一個抽象類,它為特定瞬間與一組諸如 YEARMONTHDAY_OF_MONTHHOUR 等日歷字段之間的轉換提供了一些方法,並為操作日歷字段(例如獲得下星期的日期)提供了一些方法。

在書上看到一個挺好玩的代碼,通過這個代碼淺淺的研究了下java中的Calendar類

輸出的結果是:

PS:為了學習和理解方便,我將時間調回2011年,因為2012年剛好1月1號剛好是周日。

字段操作:

三種:set(),add(),roll();

set(f, value) 將日歷字段 f 更改為 value。此外,它設置了一個內部成員變量,以指示日歷字段 f 已經被更改。盡管日歷字段 f 是立即更改的,但是直到下次調用 get()getTime()getTimeInMillis()add()roll() 時才會重新計算日歷的時間值(以毫秒為單位)。因此,多次調用 set() 不會觸發多次不必要的計算。使用 set() 更改日歷字段的結果是,其他日歷字段也可能發生更改,這取決於日歷字段、日歷字段值和日歷系統。此外,在重新計算日歷字段之后,get(f) 沒必要通過調用 set 方法返回 value 集合。具體細節是通過具體的日歷類確定的。

 

示例:假定 GregorianCalendar 最初被設置為 1999 年 8 月 31 日。調用 set(Calendar.MONTH, Calendar.SEPTEMBER) 將該日期設置為 1999 年 9 月 31 日。如果隨后調用 getTime(),那么這是解析 1999 年 10 月 1 日的一個暫時內部表示。但是,在調用 getTime() 之前調用 set(Calendar.DAY_OF_MONTH, 30) 會將該日期設置為 1999 年 9 月 30 日,因為在調用 set() 之后沒有發生重新計算。

 

  個人建議先跳過規則看下示例,然后再回過來理解。

add(f, delta)delta 添加到 f 字段中。這等同於調用 set(f, get(f) + delta),但要帶以下兩個調整:

  Add 規則 1。調用后 f 字段的值減去調用前 f 字段的值等於 delta,以字段 f 中發生的任何溢出為模。溢出發生在字段值超出其范圍時,結果,下一個更大的字段會遞增或遞減,並將字段值調整回其范圍內。

  Add 規則 2。如果期望某一個更小的字段是不變的,但讓它等於以前的值是不可能的,因為在字段 f 發生更改之后,或者在出現其他約束之后,比如時區偏移量發生更改,它的最大值和最小值也在發生更改,然后它的值被調整為盡量接近於所期望的值。更小的字段表示一個更小的時間單元。HOUR 是一個比 DAY_OF_MONTH 小的字段。對於不期望是不變字段的更小字段,無需進行任何調整。日歷系統會確定期望不變的那些字段。

此外,與 set() 不同,add() 強迫日歷系統立即重新計算日歷的毫秒數和所有字段。

 

示例:假定 GregorianCalendar 最初被設置為 1999 年 8 月 31 日。調用 add(Calendar.MONTH, 13) 將日歷設置為 2000 年 9 月 30 日。Add 規則 1MONTH 字段設置為 September,因為向 August 添加 13 個月得出的就是下一年的 September。因為在 GregorianCalendar 中,DAY_OF_MONTH 不可能是 9 月 31 日,所以 add 規則 2DAY_OF_MONTH 設置為 30,即最可能的值。盡管它是一個更小的字段,但不能根據規則 2 調整 DAY_OF_WEEK,因為在 GregorianCalendar 中的月份發生變化時,該值也需要發生變化。

 

以下是代碼,書上的代碼及注釋+我自己的理解和調試觀察。

import java.text.DateFormatSymbols;
import java.util.*;

/**
*
@version 1.4 2007-04-07
*
@author Cay Horstmann
*/

public class CalendarTest
{
public static void main(String[] args)
{
// construct d as current date
//GregorianCalendar 是 Calendar 的一個具體子類,提供了世界上大多數國家/地區使用的標准日歷系統。
//用來表示默認地區。默認時區的當前時間。
GregorianCalendar d = new GregorianCalendar();

int today = d.get(Calendar.DAY_OF_MONTH);
int month = d.get(Calendar.MONTH);//0為第一個月

//以下一段代碼是測試,類里面的一些方法,測試娛樂。
/*
* int hour = d.get(Calendar.HOUR_OF_DAY);//0~23
* int minute = d.get(Calendar.MINUTE); //0~59
* int second = d.get(Calendar.SECOND); //0~59
* System.out.println(month+1+"月"+today+"日"+hour+"時"+minute+"分"+second+"秒");
*/

// set d to start date of the month
d.set(Calendar.DAY_OF_MONTH, 1);

//Sunday==1; 1<=weekday<=7;
int weekday = d.get(Calendar.DAY_OF_WEEK);
//因為是周六,所以weekday == 7;
//System.out.println(weekday);

// get first day of week (Sunday in the U.S.)
int firstDayOfWeek = d.getFirstDayOfWeek();
//firstDayOfWeek==1;

// determine the required indentation for the first line
int indent = 0;
//一周的第一天是否是月的第一天,如果不是,則追溯到上個月找到這個周的第一天所在的時間。
while (weekday != firstDayOfWeek)
{
indent++;
d.add(Calendar.DAY_OF_MONTH, -1);
weekday = d.get(Calendar.DAY_OF_WEEK);
//int temp=d.get(Calendar.DAY_OF_MONTH);
//System.out.println(temp);
}

/*
* DateFormatSymbols 是用於壓縮本地化的日期_時間格式化數據,如月份名稱、星期名稱和時區數據的公有類。
*
* public String[] getShortWeekdays()
* 獲得短型工作日字符串。 例如:"Sun", "Mon" 等。
* 返回值:短型工作日字符串。
*/
// print weekday names
String[] weekdayNames = new DateFormatSymbols().getShortWeekdays();
/*
* 以下循環操作類似於這個,但是前面一系列操作用於確定第一天是從周幾開始(因地區而異)。所以不用我下面這兩行程序
* for(int i=1; i<=7; i++)
* System.out.printf("%s", weekdayNames[i]);
*
* 此時:weekday == firstDayOfWeek
* 但地下循環為先執行后判斷,即從周的選定的第一天 開始循環7次
*/
do
{
System.out.printf("%4s", weekdayNames[weekday]);
d.add(Calendar.DAY_OF_MONTH, 1);
weekday = d.get(Calendar.DAY_OF_WEEK);
}while (weekday != firstDayOfWeek);
System.out.println();

//月的1號一般不是從周的第一天開始。比如:周的第一天是周日,而2011年的第一天是周六,空出前6天的位置。
for (int i = 1; i <= indent; i++)
System.out.print(" ");

d.set(Calendar.DAY_OF_MONTH, 1);
do
{
// print day
int day = d.get(Calendar.DAY_OF_MONTH);
System.out.printf("%3d", day);

// mark current day with *
if (day == today) System.out.print("*");
else System.out.print(" ");

// advance d to the next day
d.add(Calendar.DAY_OF_MONTH, 1);
weekday = d.get(Calendar.DAY_OF_WEEK);

// start a new line at the start of the week
if (weekday == firstDayOfWeek) System.out.println();
}while (d.get(Calendar.MONTH) == month);
// the loop exits when d is day 1 of the next month

// print final end of line if necessary
if (weekday != firstDayOfWeek) System.out.println();
}
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM