java中的時間操作

java中的時間操作不外乎這四種情況:

1、獲取當前時間

2、獲取某個時間的某種格式

3、設置時間

4、時間的運算

好,下面就針對這三種情況,一個一個搞定。

 

一、獲取當前時間

 

有兩種方式可以獲得,第一種,使用Date類。

j2SE的包裏有兩個Date類,一個是java.sql.Date,一個是java.util.Date

這裏,要使用java.util.Date。獲取當前時間的代碼如下

Date date = new Date();

date.getTime();

還有一種方式,使用System.currentTimeMillis();

 

這兩種方式獲得的結果是一樣的,都是得到一個當前的時間的long型的時間的毫秒值,這個值實際上是當前時間值與1970年一月一號零時零分零秒相差的毫秒數。

當前的時間得到了,但實際的應用中最後往往不是要用這個long型的東西,用戶希望得到的往往是一個時間的字符串,比如“2006618號”,或“2006-06-18”,老外可能希望得到的是“06-18-2006”,諸如此類等等。這就是下一個要解決的問題

 

二、獲取某個時間的某種格式

 

獲取時間的格式,需要用到一個專門用於時間格式的類java.text.SimpleDateFormat

首先,定義一個SimpleDateFormat變量

SimpleDateFormat sdf = new SimpleDateFormat("",Locale.SIMPLIFIED_CHINESE);

這個構造函數的定義如下:

SimpleDateFormat(String pattern, Locale locale)

第一個參數pattern,我們後面再解釋,這裏我們使用一個"",第二個參數,是用來設置時區的,這裏用到了java.util.Locale這個類,這個類了面定義了很多靜態變量,直接拿過來用就OK,我們把時區設置爲Locale.SIMPLIFIED_CHINESE,只看名字,這個靜態變量的意義已經很清楚了。

 

接下來我們使用這個SimpleDateFormat把當前時間格式化爲一個如下格式的時間字符串“XXXXXXXX_XXXXXX秒”,代碼:

sdf.applyPattern("yyyy年MM月dd日_HH時mm分ss秒");

String timeStr = sdf.format(new Date());

 

獲取時間格式的函數是format,這個函數的參數是java.util.Date對象,這個沒有什麼花頭。

要說明一下的是這個pattern,所謂的模式。這裏,yyyy,MM,dd等,這就是模式。

我們可以在SimpleDateFormat的構造函數中指定模式,比如

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd",Locale.SIMPLIFIED_CHINESE);

也可以獲取時間格式的時候使用applyPattern函數臨時指定,上面的例子就是這樣。

什麼字符代表什麼,這是j2se約定好的,設置模式的時候,我們可以使用約定好的字符加上任何我們想要的字符串。

j2se對字符所代表的模式的約定列表如下:

 

 

Letter Date or Time Component Presentation
G Era designator Text
y Year Year
M Month in year Month
w Week in year Number
W Week in month Number
D Day in year Number
d Day in month Number
F Day of week in month Number
E Day in week Text
a Am/pm marker Text 
H Hour in day (0-23) Number
k Hour in day (1-24) Number
K Hour in am/pm (0-11)  Number
h   Hour in am/pm (1-12)  Number
m   Minute in hour  Number
s   Second in minute  Number
S   Millisecond  Number  
z   Time zone   General time zone 
Z   Time zone  RFC 822 time zone 

 

 

三、設置時間

 

現實中的時間是由不得我們這些凡夫俗子的,如來老頭來了也許還有點可能,但在程序裏我們可以變得神通廣大。設置時間最典型的應用就是定時任務,我們設置一個時間,到時執行某項任務。

但這裏我們主要不是爲了解決這個定時任務的問題,我們是爲了搞清楚怎麼設置時間。關於定時任務,在後面再討論怎麼做。

所謂的設置時間,其實就是我們把一個我們能看懂的時間的顯性的值(數字、字符串等),轉化成程序能看得懂的(Date類,long型的毫秒值等)告訴它。

最直接的思路是,new一個Date類,使用它的某個方法,傳進我們指定的數字或字符串類型的值,設置它的時間。

那就先來看一下Date這個類,這個類裏面有好多方法,什麼setYearsetMonth的,看起來真是太好了,傳個int值進去就搞定了。

可惜,這些看起來非常good的方法從JDK1.1以後就不用了,只有一個

setTime(long time)方法還勉強可以用,但是看看這個方法的參數吧,TNND,是個long200671號的long值是什麼?鬼才知道。

所以這個方法不可取,剛纔也提到Date類裏有很多方法從JDK1.1以後就不用了,其中就有什麼setYear,setMonth這樣的方法。這些方法不是JDK裏面沒有了,而是被Calendar類裏面的方法給取代了。(爲什麼取代?這個問題去問開發JDK的那幫人好了)

 

其實,還是用上面說到的SimpleDateFormat就可以搞定,代碼,三行:

SimpleDateFormat sdf = new SimpleDateFormat("",Locale.SIMPLIFIED_CHINESE);

sdf.applyPattern("yyyyMMdd_HHmmss");

Date date = sdf.parse("20060701_140000");

 

一看就懂了吧,第一行是聲明對象的,如果前面已經聲明瞭,這一行也省了,第二行是設置模式(pattern)的,關於這個模式,前面已經解釋的很詳細了,沒有什麼好說的。第三行,就是要設置的時間跟模式對應的字符串。第三行就返回了我們要得到的Date類型。(囉嗦了這麼半天,才囉嗦出這麼三行代碼:)

 

Ok,這個問題搞定,繼續下一個。

 

四、時間的運算

 

現在我們要開始用Calendar了,簡單介紹一下先,JDK的文檔裏說,Calendar主要是用來對Date對象和Integer對象做轉換的(這樣看起來上面那個問題我們也可以使用Calendar)。事實上,實際的開發應用中,Calendar往往用來對時間進行操作,比如說設置個時間啊,對時間進行個對比運算什麼滴。

舉個例子,已知兩個Date型時間對象,date1date2,我們需要計算出這兩個時間之間相差幾個小時,怎麼做。

一種思路:得到這兩個時間對象的long值,然後相減,這就得到了他們相差的毫秒值,然後再根據這個毫秒值算出對應的小時。代碼如下:

int distance = (int)((date2.getTime() - date1.getTime())/1000/60/60);

簡單解釋一下:

date2.getTime() - date1.getTime()得到相應的long型時間值並相減,得到相差的毫秒值,再除1000,得到秒,再除60,得到分,再除60,得到小時。呵呵,我真是夠囉嗦!從毫秒轉化成秒的時候,我在google上搜索了半天才確定一秒等於1000毫秒,真是白癡:)

 

按上面的方式,似乎問題已經解決了。但是,結果得到的小時值很大可能是個小數,而且,有可能是個小數位很長的小數,這樣就要考慮精確位的問題,上面那行代碼就不夠用了;還有一個比較關鍵的問題是,根據我們的習慣,往往可能是希望知道他們相差幾小時幾分幾秒,而不是幾點幾個小時,也可能我們只想知道他們差幾個小時,至於小時之外還差幾分幾秒,我們不感興趣,這樣,上面那行代碼也不夠用了。

如果要解決這種方式帶來的後續的這兩個問題,還要寫更多的代碼,麻煩死了,我是個懶人,不想費那腦子,我需要找一種更直接,更簡單的方式來解決。

 

終於輪到Calendar出場了,對上面的問題,解決的代碼如下:

Calendar ca1 = Calendar.getInstance();

Calendar ca2 = Calendar.getInstance();

ca1.setTime(date1);

ca2.setTime(date2);

int distanceHour = ca2.get(Calendar.HOUR_OF_DAY) - ca1.get(Calendar.HOUR_OF_DAY);

 

雖然有五行代碼,但這五行代碼根本都不用費我的腦子考慮,不像前面的,還要考慮轉化什麼的,而且這五行代碼完全可以像前面一樣用一行代碼搞定。

這樣就得到了這兩個時間相差的小時的值,我可以保證絕對是個整數,因爲這個distanceHour只是這兩個時間對象的小時數之差,而不考慮它們的分秒的差,如果想得它們差幾分,代碼如下

int distanceMin = ca2.get(Calendar.MINUTE) - ca1.get(Calendar.MINUTE);

 

解釋一下上面的代碼:

Calendar ca1 = Calendar.getInstance();

得到一個Calendar對象,Calendar不提供公用的構造函數,不能new。這行代碼得到的新對象的時間設置爲當前時間。

ca1.setTime(date1);

Calendar對象的時間設置爲date1的時間。

ca1.get(Calendar.HOUR_OF_DAY)

獲取Calendar對象的小時值,這裏得到的是24小時制的。這個get方法參數是int型的,用來指定想要獲取的域(field),就是什麼年啊月啊周啊小時的東西。參數需要用Calendar類定義的常量,每個常量對應一個域(field),這些常量的含義都很明顯(都可以顧名思義出來),用的時候在IDE環境裏直接打點選擇就可以。

這個get方法用起來很靈活,比如得到一天的int值,我們可以得到這一天一個月裏的第幾天,也可以得到一週裏的第幾天,也可以得到一年裏的第幾天,只要傳進對應的參數就OK了。

有一點需要注意的是,按照我們的習慣,週一是一週的第一天,而老外的習慣是週日纔是第一天,他們是先做完禮拜纔開始這一週的。所以如果今天是週一,我們使用ca1.get(Calendar.DAY_OF_WEEK)時得到的值是2

 

 

前面提到,Canlendar也可以用來設置時間,代碼如下

Calendar ca = Calendar.getInstance();

ca.set(Calendar.YEAR, 2006);

ca.set(Calendar.MONTH, 7);

ca.set(Calendar.DAY_OF_MONTH, 1);

ca.set(Calendar.HOUR_OF_DAY, 14);

ca.set(Calendar.MINUTE,0);

ca.set(Calendar.SECOND, 0);

Date date = ca.getTime();

這跟前面第三個問題中的那三行代碼的結果基本上是一樣的,爲什麼說基本上?因爲毫秒值不一樣,ca的毫秒值是當前時間的毫秒值,而我們沒有進行設置,所以仍然是當前的毫秒值。用那三行代碼,還是用這幾行,任君選擇。

 

 

關於定時任務,似乎跟時間操作的聯繫並不是很大,但是前面既然提到了定時任務,索性在這裏一起解決了。

設置定時任務很簡單,用Timer類就搞定了。

 

一、延時執行

 

首先,我們定義一個類,給它取個名字叫TimeTask,我們的定時任務,就在這個類的main函數裏執行。代碼如下:

package test;

import java.util.Timer;

public class TimeTask {

 

public static void main(String[] args){

Timer timer = new Timer();

timer.schedule(new Task(), 60 * 1000);

}

}

 

解釋一下上面的代碼。

上面的代碼實現了這樣一個功能,當TimeTask程序啓動以後,過一分鐘後執行某項任務。很簡單吧:先new一個Timer對象,然後調用它的schedule方法,這個方法有四個重載的方法,這裏我們用其中一個,

public void schedule(TimerTask task,long delay)

 

首先,第一個參數

 

第一個參數就是我們要執行的任務。

這是一個TimerTask對象,確切點說是一個實現TimerTask的類的對象,因爲TimerTask是個抽象類。上面的代碼裏面,Task就是我們自己定義的實現了TimerTask的類,因爲是在同一個包裏面,所以沒有顯性的import進來。Task類的代碼如下 

 

package test;

import java.util.TimerTask;

public class Task extends TimerTask {

public void run(){

System.out.println("定時任務執行");

}

}

我們的Task必須實現TimerTask的方法run,要執行的任務就在這個run方法裏面,這裏,我們只讓它往控制檯打一行字。

 

第二個參數

 

第二個參數是一個long型的值。這是延遲的時間,就是從程序開始以後,再過多少時間來執行定時任務。這個long型的值是毫秒數,所以前面我們的程序裏面,過一分鐘後執行用的參數值就是 60 * 1000。

 

二、循環執行

 

設置定時任務的時候,往往我們需要重複的執行這樣任務,每隔一段時間執行一次,而上面的方法是隻執行一次的,這樣就用到了schedule方法的是另一個重載函數

public void schedule(TimerTask task,long delay,long period)

 

前兩個參數就不用說什麼了,最後一個參數就是間隔的時間,又是個long型的毫秒數(看來java裏涉及到時間的,跟這個long是脫不了干係了),比如我們希望上面的任務從第一次執行後,每個一分鐘執行一次,第三個參數值賦60 * 1000就ok了。

 

三、指定執行時間

 

既然號稱是定時任務,我們肯定希望由我們來指定任務指定的時間,顯然上面的方法就不中用了,因爲我們不知道程序什麼時間開始運行,就沒辦法確定需要延時多少。沒關係,schedule四個重載的方法還沒用完呢。用下面這個就OK了:

public void schedule(TimerTask task,Date time)

比如,我們希望定時任務20067200分執行,只要給第二個參數傳一個時間設置爲20067200分的Date對象就可以了。

有一種情況是,可能我們的程序啓動的時候,已經是200673日了,這樣的話,程序一啓動,定時任務就開始執行了。

 

schedule最後一個重載的方法是

public void schedule(TimerTask task,Date firstTime,long period)

 

沒必要說什麼了吧:)

 

四、j2ee中的定時任務

在實際的項目中,往往定時任務需要對web工程中的資源進行操作,這樣一來,用上面的單個程序的方式可能就有點力不從心了,因爲很多web工程的資源它操作不到。

解決的辦法是,使用Servlet,把執行定時任務的那些代碼放到Servletinit()函數裏就可以了,這個easy,就沒有必要再寫示例代碼了吧(嘿嘿,其實是作者太懶了)。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章