最近在無聊的看書,遇到一編程題目,問題描述以下: 黑色星期五源於西方迷信:耶穌基督死於星期五,而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