import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import org.apache.commons.lang3.time.DateUtils; public class calendarTest { // Calendar的做用:設置日期時間、對日曆字段進行加減操做,得到日曆字段的詳細信息 public static void main(String[] args) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Calendar cal = Calendar.getInstance(); // TODO get方法 返回給定日曆字段的值。 // 獲取當前年份 int year = cal.get(Calendar.YEAR); // 獲取當前月份 Calendar.MONTH從0開始 int month = (cal.get(Calendar.MONTH)) + 1; // 獲取當前天是當前月的第幾天:即當前日期 int day_of_month = cal.get(Calendar.DAY_OF_MONTH); // Calendar.DAY_OF_MONTH 和 Calendar.DATE 是等價的 int date = cal.get(Calendar.DATE); // 獲取當前小時數:HOUR_OF_DAY-24小時制 int hour24 = cal.get(Calendar.HOUR_OF_DAY); // HOUR-12小時制 int hour12 = cal.get(Calendar.HOUR); // 獲取當前分鐘數 int minute = cal.get(Calendar.MINUTE); // 獲取當期秒數 int second = cal.get(Calendar.SECOND); // 獲取當前天是當前天然周的第幾天 Calendar.DAY_OF_WEEK用數字(1~7)表示(星期日~星期六) int day_of_week = cal.get(Calendar.DAY_OF_WEEK); // 0-上午;1-下午 int ampm = cal.get(Calendar.AM_PM); // 獲取當前日期所在的天然周是當前年的第幾個天然周 int week_of_year = cal.get(Calendar.WEEK_OF_YEAR); // 獲取當前日期所在的天然周是當前月的第幾個天然周 int week_of_month = cal.get(Calendar.WEEK_OF_MONTH); // 獲取當前日期所在的非天然周是當前月中的第幾個非天然周 (1-7第一週) int day_of_week_in_month = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH); // 獲取當前日期是當前年的第幾天 int day_of_year = cal.get(Calendar.DAY_OF_YEAR); // 獲取一個天然周的第一天是星期幾;目前默認的一週的第一天是周天。 int FirstDayOfWeek = cal.getFirstDayOfWeek(); // 返回指定日曆字段實際擁有的最大值。 // month:11;day_of_month:28,29,30,31;day_of_year:365,366 int ActualMaximum = cal.getActualMaximum(Calendar.DAY_OF_YEAR); // 返回指定日曆字段擁有的最大值。 // month:11;day_of_month:31;day_of_year:366 int Maximum = cal.getMaximum(Calendar.DAY_OF_YEAR); // 返回指定日曆字段實際擁有的最小值。 // year:1;month:0;day_of_month:1;day_of_year:1;week_of_year:1 int ActualMinimum = cal.getActualMinimum(Calendar.DAY_OF_YEAR); // 返回指定日曆字段擁有的最小值。 // year:1;month:0;day_of_month:1;day_of_year:1;week_of_year:1 int Minimum = cal.getMinimum(Calendar.DAY_OF_YEAR); // Calendar轉Date Date date1 = cal.getTime(); // Date轉Calendar cal.setTime(date1); cal.set(Calendar.YEAR, 2016); Calendar cal1 = Calendar.getInstance(); System.out.println("1111111:" + cal); System.out.println(cal.getTime()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(cal1.getTime()); System.out.println("22222222:" + cal1); // TODO set方法 // 將給定的日曆字段設置爲給定值(定位),在使用set方法以前,建議先clear()一下,不然不少信息會繼承自系統當前時間 // 注意事項:若是set()的日期不合法,就會日後找,自動轉換爲合法的日期 // 如set 2017-09-31,9月沒有31,就會日後找,找一天,實際日期應該爲2017-10-1 System.out.println(cal.getTime()); cal.clear(); System.out.println(cal.getTime()); cal.set(2017, Calendar.SEPTEMBER, 30); System.out.println("合法日期2017-9-30 :" + sdf.format(cal.getTime())); cal.set(2017, Calendar.SEPTEMBER, 31); System.out.println("2017-9-31設置爲合法日期:" + sdf.format(cal.getTime())); // 獲得今年的實際最大的星期數 int weeks = cal.getActualMaximum(Calendar.WEEK_OF_YEAR); System.out.println("今年的實際星期數:" + weeks); // 設置一個不合法的星期數 cal.set(Calendar.WEEK_OF_YEAR, 60); System.out.println("日後找到" + cal.get(Calendar.YEAR) + "年的第" + cal.get(Calendar.WEEK_OF_YEAR) + "周"); // TODO add方法 根據日曆的規則,爲給定的日曆字段添加或減去指定的時間量。 // add()有兩條規則: // 1.當被修改的字段超過它能夠的範圍時,那麼比它大的字段會自動修正。 // 2.若是比它小的字段在修正後的日期內是合法的,則小字段不須要改變;不然小字段會修正到變化最小的合法值。 // 例1 8 cal.set(2017, Calendar.AUGUST, 31); // 規則1:沒有超過範圍,不用改變大的字段(年份不變) cal.add(Calendar.MONTH, 1); // 規則2:比其小的字段不合法(日期改變),修正到變化最小的值,爲30便可 System.out.println("add方法規則:" + sdf.format(cal.getTime()));// 結果是2017-09-30 // 例2 cal.set(2017, Calendar.AUGUST, 31); // 規則1:超過範圍,改變大的字段(年份不變)(年份改成2018) // 規則2:比其小的字段不合法(日期改變),變化最小值,爲30便可 cal.add(Calendar.MONTH, 13); System.out.println("add方法規則:" + sdf.format(cal.getTime()));// 結果是2018-09-30 // TODO roll方法 和add方法同樣,區別就是 當被修改的字段超出它能夠的範圍時,那麼比它大的字段不會被修正 // 1.當被修改的字段超過它能夠的範圍時,那麼比它大的字段不會自動修正。 // 2.若是比它小的字段在修正後的日期內是合法的,則小字段不須要改變;不然小字段會修正到變化最小的合法值。 // 例1 cal.set(2017, Calendar.AUGUST, 31); cal.roll(Calendar.MONTH, 13); System.out.println("roll方法規則:" + sdf.format(cal.getTime()));// 結果是2017-09-30 // 求某月的第一天和最後一天 cal.set(Calendar.DAY_OF_MONTH, 1); System.out.println("月中的第一天:" + sdf.format(cal.getTime())); cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); System.out.println("月中的最後一天:" + sdf.format(cal.getTime())); // 求上月的最後一天 cal.add(Calendar.MONTH, -1); cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); System.out.println("上月的最後一天:" + sdf.format(cal.getTime())); // 求兩個日期間的時間差() Calendar c1 = Calendar.getInstance(); c1.clear(); c1.set(2017, Calendar.SEPTEMBER, 20, 15, 52, 35); Calendar c2 = Calendar.getInstance(); c2.clear(); c2.set(2017, Calendar.SEPTEMBER, 26, 14, 52, 35); long l1 = c1.getTimeInMillis(); long l2 = c2.getTimeInMillis(); long l3 = (l2 - l1) / 1000 / 60 / 60 / 24;// 天數 long l4 = (l2 - l1) / 1000 / 60 / 60 % 24;// 小時 long l5 = (l2 - l1) / 1000 / 60 % 60;// 分 long l6 = (l2 - l1) / 1000 % 60;// 秒 System.out.println("時間相差" + l3 + "天" + l4 + "小時" + l5 + "分" + l6 + "秒"); // 求n天以後的日期 c2 = Calendar.getInstance(); c2.add(Calendar.DATE, 4); System.out.println("n天以後的日期:" + sdf.format(c2.getTime())); // 計算某一天是一年中的第幾個星期 String s = "2018-1-7"; Date dd = DateUtils.parseDate(s, "yyyy-MM-dd"); c2.setTime(dd); System.out.println("當年的第" + c2.get(Calendar.WEEK_OF_YEAR) + "周"); // 計算一年中第幾周的星期幾是幾號 c2 = Calendar.getInstance(); System.out.println(c2.get(Calendar.WEEK_OF_YEAR)); cal.set(Calendar.YEAR, 2017); cal.set(Calendar.WEEK_OF_YEAR, c2.get(Calendar.WEEK_OF_YEAR)); cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); System.out.println("今天是" + cal.get(Calendar.DAY_OF_MONTH) + "號"); // TODO 毫秒的3種獲取方式 System.currentTimeMillis(); Calendar.getInstance().getTimeInMillis(); new Date().getTime(); // 性能比較 long times = 10000000l; long t1 = System.currentTimeMillis(); testSystem(times); long t2 = System.currentTimeMillis(); System.out.println("system耗時:" + (t2 - t1)); testCalendar(times); long t3 = System.currentTimeMillis(); System.out.println("Calendar耗時:" + (t3 - t2)); testDate(times); long t4 = System.currentTimeMillis(); System.out.println("Date耗時:" + (t4 - t3)); // 結果發現System.currentTimeMillis()和new // Date().getTime()獲取的速度差很少;Calendar.getInstance().getTimeInMillis() // 這種方式速度最慢,看源碼會發現,Canlendar由於要處理時區問題會耗費不少的時間。因此建議多使用第一種方式或第二種。 // TODO 納秒的做用 // java中System.nanoTime()返回的是納秒,可是不能用它來計算當前日期. // 此返回值表示從某一固定但任意的時間算起的納秒數(或許從之後算起,因此該值可能爲負)。 // nanoTime主要的用途是衡量一個時間段,好比說一段代碼執行所用的時間,獲取數據庫鏈接所用的時間,網絡訪問所用的時間等。 // TODO java.util.Date和java.sql時間類的區別及應用 // java.util.Date 是 java.sql.Date 的父類,前者是經常使用的表示時間的類,後者在讀寫數據庫的時候用。 // java.sql包下給出三個與數據庫相關的日期時間類型,分別是: // Date:表示日期,只有年月日,沒有時分秒。會丟失時間; // Time:表示時間,只有時分秒,沒有年月日。會丟失日期; // Timestamp:表示時間戳,有年月日時分秒,以及毫秒。 java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis()); System.out.println(sqlDate);// 2017-09-26 java.sql.Time sqlTime = new java.sql.Time(System.currentTimeMillis()); System.out.println(sqlTime);// 16:10:43 java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(System.currentTimeMillis()); System.out.println(sqlTimestamp);// 2017-09-26 16:10:43.043 // 相互轉換 // 把數據庫的三種時間類型賦給java.util.Date,基本不用轉換,由於這是把子類對象給父類的引用。 java.util.Date d1 = sqlDate; java.util.Date d2 = sqlTime; java.util.Date d3 = sqlTimestamp; // 當須要把java.util.Date轉換成數據庫的三種時間類型時,這就不能直接賦值了,這須要使用數據庫三種時間類型的構造器。 // java.sql包下的Date、Time、TimeStamp三個類的構造器都須要一個long類型的參數,表示毫秒值(時間戳)。 // 建立這三個類型的對象,只須要有毫秒值便可。咱們知道java.util.Date有getTime()方法能夠獲取毫秒值,那麼這個轉換也就不是什麼問題了。 java.util.Date d = new java.util.Date(); java.sql.Date d4 = new java.sql.Date(d.getTime());// 會丟失時分秒 java.sql.Time d5 = new java.sql.Time(d.getTime());// 會丟失年月日 java.sql.Timestamp d6 = new java.sql.Timestamp(d.getTime()); // TODO 兩個new Date()對象的hasCode()值同樣的緣由。 // 是由於Date類重寫了生成hashCode的方法。以對象當前的毫秒值爲基礎生成。所以,若是在同一時間作new // Date()操做,兩次new的時間差小於1毫秒,因此二者的毫秒值是同樣的,那麼在這個運算下生成的hashCode就是相等。 System.out.println("***********" + System.currentTimeMillis()); Date d7 = new Date(); // try { // new Thread(); // Thread.sleep(1); // } catch (InterruptedException e) { // e.printStackTrace(); // } Date d8 = new Date(); System.out.println("***********" + System.currentTimeMillis()); System.out.println("d7的hascode:" + d7.hashCode()); System.out.println("d7的hascode:" + d8.hashCode()); } public static void testSystem(long times) { for (int i = 0; i < times; i++) { System.currentTimeMillis(); } } public static void testCalendar(long times) { for (int i = 0; i < times; i++) { Calendar.getInstance().getTimeInMillis(); } } public static void testDate(long times) { for (int i = 0; i < times; i++) { new Date().getTime(); } } }