時(shí)間和日期處理
9.6 java.util包
java.util包是Java語(yǔ)言提供的工具類包,該包中包含了如日期、隨機(jī)數(shù)和數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)類等一系列的工具類實(shí)現(xiàn),是學(xué)習(xí)Java語(yǔ)言的基礎(chǔ)包之一。
本部分就以Java語(yǔ)言中常用的時(shí)間和日期處理、隨機(jī)數(shù)處理以及集合框架為基礎(chǔ)進(jìn)行介紹。
9.6.1 時(shí)間和日期處理
使用程序進(jìn)行時(shí)間和日期處理,是程序員必須的一種常用技能,在不同的程序設(shè)計(jì)語(yǔ)言中提供了不同的格式進(jìn)行實(shí)現(xiàn),現(xiàn)在就介紹一下Java語(yǔ)言中的實(shí)現(xiàn)方式,以及基本的應(yīng)用,使得對(duì)于Java語(yǔ)言的時(shí)間和日期處理技術(shù)有比較全面的認(rèn)識(shí)。
在程序中,某個(gè)固定的時(shí)間代表的都是一個(gè)時(shí)間點(diǎn),也就是一個(gè)時(shí)間的瞬間,例如2009年3月8日15點(diǎn)50分0秒,在實(shí)際的應(yīng)用中,經(jīng)常需要對(duì)于兩個(gè)時(shí)間進(jìn)行比較或計(jì)算時(shí)間之間的差值,這些功能在Java語(yǔ)言中都可以很方便的實(shí)現(xiàn)。
在Java語(yǔ)言中,時(shí)間的表達(dá)單位是毫秒。也就是說(shuō),Java語(yǔ)言中的時(shí)間處理可以精確到毫秒。
在Java語(yǔ)言中,表達(dá)時(shí)間的方式有兩種:
a、絕對(duì)時(shí)間。以直觀的形式來(lái)表達(dá)某個(gè)時(shí)間點(diǎn),例如2009年10月10號(hào)0點(diǎn)0分0秒。使用這種形式表達(dá)時(shí)間,使用起來(lái)比較直觀,但是不方便進(jìn)行時(shí)間之間的計(jì)算。例如無(wú)法很直觀的計(jì)算2020年1月1號(hào)0點(diǎn)0分0秒和上面這個(gè)時(shí)間之間相差多少天。絕對(duì)時(shí)間以對(duì)象的形式進(jìn)行表達(dá),Java API中提供了java.util包中的Date類和Calendar類的對(duì)象進(jìn)行表達(dá)。
b、相對(duì)時(shí)間。以一個(gè)long型的數(shù)字表達(dá)某個(gè)時(shí)間點(diǎn)。例如102847423468。使用這種方式的優(yōu)缺點(diǎn)和絕對(duì)時(shí)間剛好相反。這種方式很方便時(shí)間之間的計(jì)算,但是閱讀起來(lái)很不直觀。在Java API中以需要表達(dá)的時(shí)間點(diǎn),例如2009年10月10號(hào)0點(diǎn)0分0秒,和GMT(格林威治時(shí)間,也就是倫敦時(shí)間)1970年1月1號(hào)0點(diǎn)0分0秒之間相差的毫秒數(shù)作為相對(duì)時(shí)間的數(shù)值,如果該時(shí)間在這個(gè)時(shí)間只好,則相對(duì)時(shí)間為正數(shù),否則相對(duì)時(shí)間為負(fù)數(shù)。Java API中提供了java.lang包中的System類的currentTimeMillis方法,獲得以相對(duì)時(shí)間形式描述的當(dāng)前系統(tǒng)時(shí)間。
在實(shí)際使用時(shí),絕對(duì)時(shí)間和相對(duì)時(shí)間之間可以很方便的進(jìn)行轉(zhuǎn)換。
9.6.1.1 Date類
在JDK1.0中,Date類是唯一的一個(gè)代表時(shí)間的類,但是由于Date類不便于實(shí)現(xiàn)國(guó)際化,所以從JDK1.1版本開(kāi)始,推薦使用Calendar類進(jìn)行時(shí)間和日期處理。這里簡(jiǎn)單介紹一下Date類的使用。
1、使用Date類代表當(dāng)前系統(tǒng)時(shí)間
Date d = new Date();
System.out.println(d);
使用Date類的默認(rèn)構(gòu)造方法創(chuàng)建出的對(duì)象就代表當(dāng)前時(shí)間,由于Date類覆蓋了toString方法,所以可以直接輸出Date類型的對(duì)象,顯示的結(jié)果如下:
Sun Mar 08 16:35:58 CST 2009
在該格式中,Sun代表Sunday(周日),Mar代表March(三月),08代表8號(hào),CST代表China Standard Time(中國(guó)標(biāo)準(zhǔn)時(shí)間,也就是北京時(shí)間(東八區(qū)))。
2、使用Date類代表指定的時(shí)間
Date d1 = new Date(2009-1900,3-1,9);
System.out.println(d1);
使用帶參數(shù)的構(gòu)造方法,可以構(gòu)造指定日期的Date類對(duì)象,Date類中年份的參數(shù)應(yīng)該是實(shí)際需要代表的年份減去1900,實(shí)際需要代表的月份減去1以后的值。例如上面的示例代碼代表就是2009年3月9號(hào)。
實(shí)際代表具體的年月日時(shí)分秒的日期對(duì)象,和這個(gè)類似。
3、獲得Date對(duì)象中的信息
Date d2 = new Date();
//年份
int year = d2.getYear() + 1900;
//月份
int month = d2.getMonth() + 1;
//日期
int date = d2.getDate();
//小時(shí)
int hour = d2.getHours();
//分鐘
int minute = d2.getMinutes();
//秒
int second = d2.getSeconds();
//星期幾
int day = d2.getDay();
System.out.println("年份:" + year);
System.out.println("月份:" + month);
System.out.println("日期:" + date);
System.out.println("小時(shí):" + hour);
System.out.println("分鐘:" + minute);
System.out.println("秒:" + second);
System.out.println("星期:" + day);
使用Date類中對(duì)應(yīng)的get方法,可以獲得Date類對(duì)象中相關(guān)的信息,需要注意的是使用getYear獲得是Date對(duì)象中年份減去1900以后的值,所以需要顯示對(duì)應(yīng)的年份則需要在返回值的基礎(chǔ)上加上1900,月份類似。在Date類中還提供了getDay方法,用于獲得Date對(duì)象代表的時(shí)間是星期幾,Date類規(guī)定周日是0,周一是1,周二是2,后續(xù)的依次類推。
4、Date對(duì)象和相對(duì)時(shí)間之間的互轉(zhuǎn)
Date d3 = new Date(2009-1900,3-1,10);
long time = 1290876532190L;
//將Date類的對(duì)象轉(zhuǎn)換為相對(duì)時(shí)間
long t = d3.getTime();
System.out.println(t);
//將相對(duì)時(shí)間轉(zhuǎn)換為Date類的對(duì)象
Date d4 = new Date(time);
System.out.println(d4);
使用Date對(duì)象中的getTime方法,可以將Date類的對(duì)象轉(zhuǎn)換為相對(duì)時(shí)間,使用Date類的構(gòu)造方法,可以將相對(duì)時(shí)間轉(zhuǎn)換為Date類的對(duì)象。經(jīng)過(guò)轉(zhuǎn)換以后,既方便了時(shí)間的計(jì)算,也使時(shí)間顯示比較直觀了。
9.6.1.2 Calendar類
從JDK1.1版本開(kāi)始,在處理日期和時(shí)間時(shí),系統(tǒng)推薦使用Calendar類進(jìn)行實(shí)現(xiàn)。在設(shè)計(jì)上,Calendar類的功能要比Date類強(qiáng)大很多,而且在實(shí)現(xiàn)方式上也比Date類要復(fù)雜一些,下面就介紹一下Calendar類的使用。
Calendar類是一個(gè)抽象類,在實(shí)際使用時(shí)實(shí)現(xiàn)特定的子類的對(duì)象,創(chuàng)建對(duì)象的過(guò)程對(duì)程序員來(lái)說(shuō)是透明的,只需要使用getInstance方法創(chuàng)建即可。
1、使用Calendar類代表當(dāng)前時(shí)間
Calendar c = Calendar.getInstance();
由于Calendar類是抽象類,且Calendar類的構(gòu)造方法是protected的,所以無(wú)法使用Calendar類的構(gòu)造方法來(lái)創(chuàng)建對(duì)象,API中提供了getInstance方法用來(lái)創(chuàng)建對(duì)象。
使用該方法獲得的Calendar對(duì)象就代表當(dāng)前的系統(tǒng)時(shí)間,由于Calendar類toString實(shí)現(xiàn)的沒(méi)有Date類那么直觀,所以直接輸出Calendar類的對(duì)象意義不大。
2、使用Calendar類代表指定的時(shí)間
Calendar c1 = Calendar.getInstance();
c1.set(2009, 3 - 1, 9);
使用Calendar類代表特定的時(shí)間,需要首先創(chuàng)建一個(gè)Calendar的對(duì)象,然后再設(shè)定該對(duì)象中的年月日參數(shù)來(lái)完成。
set方法的聲明為:
public final void set(int year,int month,int date)
以上示例代碼設(shè)置的時(shí)間為2009年3月9日,其參數(shù)的結(jié)構(gòu)和Date類不一樣。Calendar類中年份的數(shù)值直接書(shū)寫(xiě),月份的值為實(shí)際的月份值減1,日期的值就是實(shí)際的日期值。
如果只設(shè)定某個(gè)字段,例如日期的值,則可以使用如下set方法:
public void set(int field,int value)
在該方法中,參數(shù)field代表要設(shè)置的字段的類型,常見(jiàn)類型如下:
Calendar.YEAR——年份
Calendar.MONTH——月份
Calendar.DATE——日期
Calendar.DAY_OF_MONTH——日期,和上面的字段完全相同
Calendar.HOUR——12小時(shí)制的小時(shí)數(shù)
Calendar.HOUR_OF_DAY——24小時(shí)制的小時(shí)數(shù)
Calendar.MINUTE——分鐘
Calendar.SECOND——秒
Calendar.DAY_OF_WEEK——星期幾
后續(xù)的參數(shù)value代表,設(shè)置成的值。例如:
c1.set(Calendar.DATE,10);
該代碼的作用是將c1對(duì)象代表的時(shí)間中日期設(shè)置為10號(hào),其它所有的數(shù)值會(huì)被重新計(jì)算,例如星期幾以及對(duì)應(yīng)的相對(duì)時(shí)間數(shù)值等。
3、獲得Calendar類中的信息
Calendar c2 = Calendar.getInstance();
//年份
int year = c2.get(Calendar.YEAR);
//月份
int month = c2.get(Calendar.MONTH) + 1;
//日期
int date = c2.get(Calendar.DATE);
//小時(shí)
int hour = c2.get(Calendar.HOUR_OF_DAY);
//分鐘
int minute = c2.get(Calendar.MINUTE);
//秒
int second = c2.get(Calendar.SECOND);
//星期幾
int day = c2.get(Calendar.DAY_OF_WEEK);
System.out.println("年份:" + year);
System.out.println("月份:" + month);
System.out.println("日期:" + date);
System.out.println("小時(shí):" + hour);
System.out.println("分鐘:" + minute);
System.out.println("秒:" + second);
System.out.println("星期:" + day);
使用Calendar類中的get方法可以獲得Calendar對(duì)象中對(duì)應(yīng)的信息,get方法的聲明如下:
public int get(int field)
其中參數(shù)field代表需要獲得的字段的值,字段說(shuō)明和上面的set方法保持一致。需要說(shuō)明的是,獲得的月份為實(shí)際的月份值減1,獲得的星期的值和Date類不一樣。在Calendar類中,周日是1,周一是2,周二是3,依次類推。
4、其它方法說(shuō)明
其實(shí)Calendar類中還提供了很多其它有用的方法,下面簡(jiǎn)單的介紹幾個(gè)常見(jiàn)方法的使用。
a、add方法
public abstract void add(int field,int amount)
該方法的作用是在Calendar對(duì)象中的某個(gè)字段上增加或減少一定的數(shù)值,增加是amount的值為正,減少時(shí)amount的值為負(fù)。
例如在計(jì)算一下當(dāng)前時(shí)間100天以后的日期,代碼如下:
Calendar c3 = Calendar.getInstance();
c3.add(Calendar.DATE, 100);
int year1 = c3.get(Calendar.YEAR);
//月份
int month1 = c3.get(Calendar.MONTH) + 1;
//日期
int date1 = c3.get(Calendar.DATE);
System.out.println(year1 + "年" + month1 + "月" + date1 + "日");
這里add方法是指在c3對(duì)象的Calendar.DATE,也就是日期字段上增加100,類內(nèi)部會(huì)重新計(jì)算該日期對(duì)象中其它各字段的值,從而獲得100天以后的日期,例如程序的輸出結(jié)果可能為:
2009年6月17日
b、after方法
public boolean after(Object when)
該方法的作用是判斷當(dāng)前日期對(duì)象是否在when對(duì)象的后面,如果在when對(duì)象的后面則返回true,否則返回false。例如:
Calendar c4 = Calendar.getInstance();
c4.set(2009, 10 - 1, 10);
Calendar c5 = Calendar.getInstance();
c5.set(2010, 10 - 1, 10);
boolean b = c5.after(c4);
System.out.println(b);
在該示例代碼中對(duì)象c4代表的時(shí)間是2009年10月10號(hào),對(duì)象c5代表的時(shí)間是2010年10月10號(hào),則對(duì)象c5代表的日期在c4代表的日期之后,所以after方法的返回值是true。
另外一個(gè)類似的方法是before,該方法是判斷當(dāng)前日期對(duì)象是否位于另外一個(gè)日期對(duì)象之前。
c、getTime方法
public final Date getTime()
該方法的作用是將Calendar類型的對(duì)象轉(zhuǎn)換為對(duì)應(yīng)的Date類對(duì)象,兩者代表相同的時(shí)間點(diǎn)。
類似的方法是setTime,該方法的作用是將Date對(duì)象轉(zhuǎn)換為對(duì)應(yīng)的Calendar對(duì)象,該方法的聲明如下:
public final void setTime(Date date)
轉(zhuǎn)換的示例代碼如下:
Date d = new Date();
Calendar c6 = Calendar.getInstance();
//Calendar類型的對(duì)象轉(zhuǎn)換為Date對(duì)象
Date d1 = c6.getTime();
//Date類型的對(duì)象轉(zhuǎn)換為Calendar對(duì)象
Calendar c7 = Calendar.getInstance();
c7.setTime(d);
5、Calendar對(duì)象和相對(duì)時(shí)間之間的互轉(zhuǎn)
Calendar c8 = Calendar.getInstance();
long t = 1252785271098L;
//將Calendar對(duì)象轉(zhuǎn)換為相對(duì)時(shí)間
long t1 = c8.getTimeInMillis();
//將相對(duì)時(shí)間轉(zhuǎn)換為Calendar對(duì)象
Calendar c9 = Calendar.getInstance();
c9.setTimeInMillis(t1);
在轉(zhuǎn)換時(shí),使用Calendar類中的getTimeInMillis方法可以將Calendar對(duì)象轉(zhuǎn)換為相對(duì)時(shí)間。在將相對(duì)時(shí)間轉(zhuǎn)換為Calendar對(duì)象時(shí),首先創(chuàng)建一個(gè)Calendar對(duì)象,然后再使用Calendar類的setTimeInMillis方法設(shè)置時(shí)間即可。
9.6.1.3 應(yīng)用示例
下面以兩個(gè)簡(jiǎn)單的示例介紹時(shí)間和日期處理的基本使用。
1、計(jì)算兩個(gè)日期之間相差的天數(shù)
例如計(jì)算2010年4月1號(hào)和2009年3月11號(hào)之間相差的天數(shù),則可以使用時(shí)間和日期處理進(jìn)行計(jì)算。
該程序?qū)崿F(xiàn)的原理為:首先代表兩個(gè)特定的時(shí)間點(diǎn),這里使用Calendar的對(duì)象進(jìn)行代表,然后將兩個(gè)時(shí)間點(diǎn)轉(zhuǎn)換為對(duì)應(yīng)的相對(duì)時(shí)間,求兩個(gè)時(shí)間點(diǎn)相對(duì)時(shí)間的差值,然后除以1天的毫秒數(shù)(24小時(shí)X60分鐘X60秒X1000毫秒)即可獲得對(duì)應(yīng)的天數(shù)。實(shí)現(xiàn)該示例的完整代碼如下:
import java.util.*;
/**
* 計(jì)算兩個(gè)日期之間相差的天數(shù)
*/
public class DateExample1 {
public static void main(String[] args) {
//設(shè)置兩個(gè)日期
//日期:2009年3月11號(hào)
Calendar c1 = Calendar.getInstance();
c1.set(2009, 3 - 1, 11);
//日期:2010年4月1號(hào)
Calendar c2 = Calendar.getInstance();
c2.set(2010, 4 - 1, 1);
//轉(zhuǎn)換為相對(duì)時(shí)間
long t1 = c1.getTimeInMillis();
long t2 = c2.getTimeInMillis();
//計(jì)算天數(shù)
long days = (t2 - t1)/(24 * 60 * 60 * 1000);
System.out.println(days);
}
}
2、輸出當(dāng)前月的月歷
該示例的功能是輸出當(dāng)前系統(tǒng)時(shí)間所在月的日歷,例如當(dāng)前系統(tǒng)時(shí)間是2009年3月10日,則輸出2009年3月的日歷。
該程序?qū)崿F(xiàn)的原理為:首先獲得該月1號(hào)是星期幾,然后獲得該月的天數(shù),最后使用流程控制實(shí)現(xiàn)按照日歷的格式進(jìn)行輸出即可。即如果1號(hào)是星期一,則打印一個(gè)單位的空格,如果1號(hào)是星期二,則打印兩個(gè)單位的空格,依次類推。打印完星期六的日期以后,進(jìn)行換行。實(shí)現(xiàn)該示例的完整代碼如下:
import java.util.*;
/**
* 輸出當(dāng)前月的日歷
*/
public class DateExample2{
public static void main(String[] args){
//獲得當(dāng)前時(shí)間
Calendar c = Calendar.getInstance();
//設(shè)置代表的日期為1號(hào)
c.set(Calendar.DATE,1);
//獲得1號(hào)是星期幾
int start = c.get(Calendar.DAY_OF_WEEK);
//獲得當(dāng)前月的最大日期數(shù)
int maxDay = c.getActualMaximum(Calendar.DATE);
//輸出標(biāo)題
System.out.println("星期日星期一星期二星期三 星期四 星期五 星期六");
//輸出開(kāi)始的空格
for(int i = 1;i < start;i++){
System.out.print(" ");
}
//輸出該月中的所有日期
for(int i = 1;i <= maxDay;i++){
//輸出日期數(shù)字
System.out.print(" " + i);
//輸出分隔空格
System.out.print(" ");
if(i < 10){
System.out.print(' ');
}
//判斷是否換行
if((start + i - 1) % 7 == 0){
System.out.println();
}
}
//換行
System.out.println();
}
}
關(guān)于時(shí)間和日期的處理就介紹這么多,更多的實(shí)現(xiàn)方法還需要根據(jù)具體問(wèn)題進(jìn)行對(duì)應(yīng)的實(shí)現(xiàn)。
posted on 2009-06-15 13:45 找個(gè)美女做老婆 閱讀(864) 評(píng)論(1) 編輯 收藏