Java Calendar使用


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();
		}
	}

}


免責聲明!

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



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