時間和日期處理,在一個應用中都是很重要的,掌握時間和日期類的處理也是很重要的。Java中的Calendar類和Date類,在java.util包下。在JDK1.0中,Date類是唯一處理時間的類,但是由於Date類中方法比較少並且有一些方法不便於實現國際化,所以從JDK1.1版本開始新增了Calendar類,增加了許多功能強大的方法,推薦使用 Calendar類進行時間和日期處理。下面開始總結Date類和Calendar類的一些使用方法
Date類
在Java中有兩個Date類,一個是java.sql.Date,另一個是java.util.Date,他們的關係是:前者是後者的子類,主要用在構造SQL語句的時候,比如讀寫數據庫的時候可以使用它,後者是在大多是情況下使用的。他們的用法基本都是一樣的。
Date的構造
創建一個Date類的對象,構造方法的參數可以有如下幾種:
- 無參構造方法,使用默認無參構造方法創建出來的對象表示當前系統時間:
Date date = new Date();
- long類型的時間,long類型的時間就是自1970年1月1日00:00:00這一刻開始到目前所經歷的毫秒數,這個值每時每刻都在變大,Date類可以已它作爲構造參數創建一個指定的Date,比如:
Date now = new Date(System.currentTimeMillis());
這樣就將當前系統時間封裝成了一個Date類型數據,通過這個數據能夠得到年月日等信息。
- 具體的年,月,日。傳入具體的年月日的數值(年的數值並不是表示絕對的時間,而是自1900年開始的年份,所以,如果要表示年,應爲指定值減去1900,比如要表示2015年,則應填寫(2015-1900),月份的數值是從0到11,所以如果想表示3月,月份的數值就應該填2),以構造一個指定日期的Date類型數據,得到一個指定日期0點0分0秒的Date對象:
Date date= new Date(2015-1900, 11, 27);//或者Date date = new Date(115,11,27)
- 具體到時分秒的構造方法。傳入一個具體時間的 值以構造指定時間的Date對象,比如:
Date date1=new Date(2015-1900,11,30,23,59,59);
這樣就創建了一個2015年12月30日23時59分59秒的Date對象
所有這些參數都是有取值範圍的,就像秒的範圍爲0-59一樣,如果在構造一個Date對象時參數的值超出了取值範圍,會默認往後疊加的,比如一個Date對象的構造爲:
Date oldDate = new Date(2015-1900, 4, 40);
表面上看,這樣得到的是一個2015年5月40日的Date對象,當然,肯定是不存在這個日期的,所以Date類型會自動往後疊加,打印輸出爲:
2015-06-09 00:00:00
Date的操作
構造完成後,需要對它進行一些操作,來滿足具體的需求,常用的有格式化輸入輸出,Date類型時間和String類型時間的轉換,日期比較,加減
格式化
按照指定格式輸出一個時間,爲了滿足不同的使用場景,比如有的時候僅需要顯示時分,如“12:30”有的時候需要顯示完整的時間,如“01-01 12:30”這樣不同的顯示只需要不同的格式,而Date對象不需要做任何改動,使用起來很靈活,這就需要用到SimpleDateFormat類來實現,下面是一個簡單的例子:
SimpleDateFormat format1 = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
System.out.println(format1.format(date));
System.out.println(format2.format(date));
輸出結果:
2015-11-29 20:27:24
20:27:24
可以看到,控制Date輸出顯示格式的,就是SimpleDateFormat類的構造參數,這個構造參數規範了Date輸出的格式,SimpleDateFormat中一些格式字符的含義如下:
- G: 年代標誌符
- y: 年(大小寫無區別)
- M: 月(大寫表示 月,小寫表示 分)
- d: 日(大寫表示一年中的第幾天,小寫表示 日)
- H: 時(24小時制的時間)
- m: 分
- s: 秒
- S: 毫秒
- E: 星期
- D: 一年中的第幾天
- w: 一年中第幾個星期
- W:一月中第幾個星期
- a: 上午或下午的標誌符
- k: 一天中的第幾個小時(24小時制)
- K: 一天中的第幾個小時(12小時制)
- z: 時區
有了以上字符的解釋,就能很輕鬆的構造任意格式的時間了,比如:“yyyy年mm月dd日 HH:mm:ss 是第D天 在第w周”輸出如下:
2015年52月29日 20:52:21 是第333天 在第49周
類型轉換
在很多時候需要將Date類型數據轉換成String類型數據用以顯示,或者將String類型的時間轉成Date類型用以計算比較,所以下面是通用的類型轉換代碼:
/**
* 將String類型的時間轉換成Date類型,傳入的時間格式必須要滿足下面的格式,否則會報錯
*/
public static Date str2Date(String dateStr) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
Date date = null;
try {
date = format.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
/**
* 將Date型轉換成指定格式的時間字符串
*/
public static String date2Str(Date date) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
return format.format(date);
}
時間比較
有時候需要比較兩個時間誰在前誰在後,可以使用Date類的compareTo方法來實現:
/**
* 如果d1在d2後則返回true,否則返回false
*/
public static boolean greater(Date d1, Date d2) {
//如果compareTo返回0,表示兩個日期相等,返回小於0的值,表示d1在d2之前,大於0表示d1在d2之後
return d1.compareTo(d2) > 0;
}
有時候想要獲取指定時間之前或之後一段時間的日期,如下:
/**
* 返回當前日期之後或者之前n天的時間
* n爲正數表示當前日期之後的時間
* n爲負數表示當前日期之前的時間
*/
public static Date duration(int n) {
return new Date(new Date().getTime() + n * 24 * 60 * 60 * 1000);
}
類似發佈微博後顯示距離當前時間“幾分鐘前”,“幾小時前”的日期比較可以如下實現:
/**
* 返回發佈時間距離當前的時間
*/
public static String timeAgo(Date createdTime) {
SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm", Locale.CHINA);
if (createdTime != null) {
long agoTimeInMin = (new Date(System.currentTimeMillis()).getTime() - createdTime.getTime()) / 1000 / 60;
//如果在當前時間以前一分鐘內
if (agoTimeInMin <= 1) {
return "剛剛";
} else if (agoTimeInMin <= 60) {
//如果傳入的參數時間在當前時間以前10分鐘之內
return agoTimeInMin + "分鐘前";
} else if (agoTimeInMin <= 60 * 24) {
return agoTimeInMin / 60 + "小時前";
} else if (agoTimeInMin <= 60 * 24 * 2) {
return agoTimeInMin / (60 * 24) + "天前";
} else {
return format.format(createdTime);
}
} else {
return format.format(new Date(0));
}
}
。。。未完待續