java Date和Calendar類

最近在無聊的看書,遇到一編程題目,問題描述以下:
 黑色星期五源於西方迷信:耶穌基督死於星期五,而13也是一個不吉利的數字。黑色星期五即該日同時是星期五又是13號,求將來幾年內這樣的日子。
基於該問題會涉及到java中的關於時間類的部分,故嘗試經過該題目總結現階段的java Date和calendar類的問題。
1、Date類
  查閱API文檔可知,Date類源於jdk1.0版本,並在jdk1.1版本中其絕大多數方法被Calendar類中方法所代替。Date類構造函數public且未abstrct,故能夠建立Date對象。
    public static void main(String[] args) {
	    Date date = new Date();
	    System.out.println(date);
    }

   運行結果爲:Sat Dec 19 21:46:14 CST 2015 ,分別表示系統當期星期、月份、時間、時區、年份。java

   查看Date類構造函數源碼以下,大體可瞭解到Date初始化獲取時間戳,即系統當前時間與1970年01月01日00時00分00秒的差值,從而獲取系統當前日期。編程

    public Date() {
         this(System.currentTimeMillis());
    }
    public Date(long date) {
           fastTime = date;
      }
    private transient long fastTime;

 

  依據API文檔對該類介紹,可大體瞭解到其因爲java虛擬機d主機環境沒法準確描述時間,從 JDK 1.1 開始,應該使用 Calendar 類實現日期和時間字段之間轉換,使用 DateFormat 類來格式化和解析日期字符串。Date 中的相應方法已廢棄。app

 2、DateFormat類函數

  查看該類的API文檔可知該類抽象,沒法建立建立對象,但其子類SimpleDateFormat類繼承該類。this

 3、SimpleDateFormat類設計

  java面向對象強調封裝,將多種操做的方法封裝至一類中,若是該類所表明的事務可以關聯其操做方法時。此處體如今於java將日期類的格式化的全部操做封裝至一類DateFormat中,並由其子類SimpleDateFormat實現全部操做方法。code

	public static void main(String[] args){
		Date date = new Date();
		String pattern = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		String time = sdf.format(date);
		System.out.println(time);
	}
    

  運行結果:2015-12-19   orm

  字符串pattern表示格式化的要求格式,將要求格式經過SimpleDateFormat的構造函數傳入再經過調用format方法格式Date類的對象,從而獲得所須要的類型。對象

  固然,針對於SimpleDateFormat類,也能夠調用applyPattern將要求格式傳遞給sdf。  blog

      public void applyPattern(String pattern) {
            applyPatternImpl(pattern);
      }

      private void applyPatternImpl(String pattern) {
            compiledPattern = compile(pattern);
            this.pattern = pattern;
      }

  源碼說明,applyPattern將要求格式pattern傳遞給類全局變量pattern。

  格式pattern的值則能夠依據下表根據需求而定(注意大小寫區別):

    字母 	日期或時間元素 	表示 	示例
    G 	Era 標誌符 	Text 	AD
    y 	年 	Year 	1996; 96
    M 	年中的月份 	Month 	July; Jul; 07
    w 	年中的週數 	Number 	27
    W 	月份中的週數 	Number 	2
    D 	年中的天數 	Number 	189
    d 	月份中的天數 	Number 	10
    F 	月份中的星期 	Number 	2
    E 	星期中的天數 	Text 	Tuesday; Tue
    a 	Am/pm 標記 	Text 	PM
    H 	一天中的小時數(0-23) 	Number 	0
    k 	一天中的小時數(1-24) 	Number 	24
    K 	am/pm 中的小時數(0-11) 	Number 	0
    h 	am/pm 中的小時數(1-12) 	Number 	12
    m 	小時中的分鐘數 	Number 	30
    s 	分鐘中的秒數 	Number 	55
    S 	毫秒數 	Number 	978
    z 	時區 	General time zone 	Pacific Standard Time; PST; GMT-08:00
    Z 	時區 	RFC 822 time zone 	-0800

  4、Calendar類

  Calendar類也是抽象類,可使用其具體實現的子類GregorianCalendar建立子類對象來實現日期與時間字段間的轉換。查看Calendar類,其構造函數protected,絕大多數方法使用static修飾,使用單例模式設計而成,getInstance方法返回該類的對象。 

      public static Calendar getInstance() {
            return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
      }

   使用該方法獲取對象後打印以下:

	public static void main(String[] args){
		Calendar cal = Calendar.getInstance();
		System.out.println(cal);
	}

   打印結果:

    java.util.GregorianCalendar[time=1450573269561,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Chongqing",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=11,WEEK_OF_YEAR=52,WEEK_OF_MONTH=4,DAY_OF_MONTH=20,DAY_OF_YEAR=354,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=9,HOUR_OF_DAY=9,MINUTE=1,SECOND=9,MILLISECOND=561,ZONE_OFFSET=28800000,DST_OFFSET=0]

   該類對象內以鍵值對形式封裝了全部日期時間類信息,與Date類相比,信息更豐富完整。使用Calendar的字段屬性可快速得到所對應的鍵值。    

	public static void main(String[] args){
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH)+1;//月份從0開始計算
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int week = cal.get(Calendar.DAY_OF_WEEK);//星期日默認星期開始第一天
		System.out.println(year+"-"+month+"-"+day+":"+week);
	}

   運行結果:2015-12-20:1

   除了獲取當前時間外,Calendar還能夠設置當前時間,和時間的自動加減。設置時間以下:

	public static void main(String[] args){
		Calendar cal = Calendar.getInstance();	
		cal.set(Calendar.YEAR, 2012);
		cal.set(Calendar.MONTH, 0);
		cal.set(Calendar.DAY_OF_MONTH,13);
		
		
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH)+1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int week = cal.get(Calendar.DAY_OF_WEEK);
		System.out.println(year+"-"+month+"-"+day+":"+week);
	}

   運行結果:2012-1-13:6

	public static void main(String[] args){
		Calendar cal = Calendar.getInstance();	
		cal.set(Calendar.YEAR, 2012);
		cal.set(Calendar.MONTH, 0);
		cal.set(Calendar.DAY_OF_MONTH,13);
		
		
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH)+1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int week = cal.get(Calendar.DAY_OF_WEEK);
		
		cal.add(Calendar.MONTH, 1);
		year = cal.get(Calendar.YEAR);
		month = cal.get(Calendar.MONTH)+1;
		day = cal.get(Calendar.DAY_OF_MONTH);
		week = cal.get(Calendar.DAY_OF_WEEK);
		
		System.out.println(year+"-"+month+"-"+day+":"+week);
	}

   運行結果:2012-2-13:2
   Cal.add(calendar.MONTH, 1)會實現month月份自動加一,且其增長會致使YEAR進位,即滿十二進一。

  故黑色星期五的解法可以下:

	public static void method(){
		Calendar cal = Calendar.getInstance();	
		cal.set(Calendar.YEAR, 2012);
		cal.set(Calendar.MONTH, 0);
		cal.set(Calendar.DAY_OF_MONTH,13);
				
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH)+1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int week = cal.get(Calendar.DAY_OF_WEEK);
		while(year < 2017){
			if(week == 6){
				System.out.println(year+"-"+month+"-"+day);
			}
//			month++;
			cal.add(Calendar.MONTH, 1);
			year = cal.get(Calendar.YEAR);
			month = cal.get(Calendar.MONTH)+1;
			day = cal.get(Calendar.DAY_OF_MONTH);
			week = cal.get(Calendar.DAY_OF_WEEK);
		}
//		System.out.println(year +" "+ month+" "+ day+" "+week);
		
	}

   運行結果:

      2012-1-13
      2012-4-13
      2012-7-13
      2013-9-13
      2013-12-13
      2014-6-13
      2015-2-13
      2015-3-13
      2015-11-13
      2016-5-13
相關文章
相關標籤/搜索