時間加減
Date currentDate = new Date(System.currentTimeMillis());
Calendar cal = Calendar.getInstance();
cal.setTime(currentDate);
cal.add(Calendar.DAY_OF_MONTH, -1);//減一天時間
startTime=outputFormat.format(cal.getTime());
開發(fā)跨地域的程序時癞揉,常需要進(jìn)行時區(qū)轉(zhuǎn)換噪裕,一個設(shè)計(jì)優(yōu)良的系統(tǒng)株婴,也必須考慮對多時區(qū)的支持怎虫。JDK提供了很多方便的機(jī)制和工具暑认,來幫助我們解決時區(qū)轉(zhuǎn)換問題。
解決跨時區(qū)問題的關(guān)鍵在于時間的記錄形式大审。若將時間單純的記錄成“2011-05-14 23:30:00”蘸际,其中蘊(yùn)含的信息并不足以進(jìn)行時區(qū)轉(zhuǎn)換,因?yàn)闊o法獲知這是中國的23點(diǎn)30徒扶,還是美國的23點(diǎn)30粮彤,更不用說復(fù)雜的夏令時問題了。
我們可以使用一個long類型的變量來記錄時間姜骡,該變量的值等于從1970年1月1日 00:00:00 GMT到記錄時間點(diǎn)以來的毫秒數(shù)导坟,其中GMT代表格林威治標(biāo)準(zhǔn)時間,通過這個差值圈澈,可以獲得記錄時間點(diǎn)的格林威治(零時區(qū))時間惫周,進(jìn)而能方便的轉(zhuǎn)換成全世界各時區(qū)的時間。(很多數(shù)據(jù)庫引擎就是如此處理時間類型數(shù)據(jù))
在Java中康栈,有兩個常用方法來獲取以上描述的值:
- System.currentTimeMillis()递递,該方法的返回值是從1970年1月1日 00:00:00 GMT至當(dāng)前時間點(diǎn)以來的毫秒數(shù),通常被用來獲取當(dāng)前系統(tǒng)時間啥么;
- java.util.Date的getTime()登舞,該方法的返回值是從1970年1月1日 00:00:00 GMT至Date對象所表示的時間點(diǎn)以來的毫秒數(shù),通常被用來獲取特定的時間饥臂。
此外逊躁,我們還需要借助java.util.TimeZone類,來獲取特定的時區(qū)隅熙,JRE安裝目錄下的\lib\zi文件夾列出了所有TimeZoneID稽煤,如:Asia/Shanghai。最后囚戚,使用java.text.SimpleDateFormat類提供的方法進(jìn)行轉(zhuǎn)換酵熙,并格式化輸出。
//1. 將系統(tǒng)當(dāng)前時間轉(zhuǎn)換成美國東部時間
// America/Los_Angeles 洛杉磯時間
TimeZone timeZoneNY = TimeZone.getTimeZone("America/New_York");
SimpleDateFormat outputFormat = new SimpleDateFormat("EEE MMM d HH:mm:ss Z yyyy", Locale.US);
outputFormat.setTimeZone(timeZoneNY);
Date date = new Date(System.currentTimeMillis());
System.out.println(outputFormat.format(date));
//2. 將一個以字符串形式輸入的北京時間轉(zhuǎn)換成美國東部時間
String inputDate = "2011-05-14 23:30:00";
TimeZone timeZoneSH = TimeZone.getTimeZone("Asia/Shanghai");
TimeZone timeZoneNY = TimeZone.getTimeZone("America/New_York");
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
inputFormat.setTimeZone(timeZoneSH);
Date date = null;
try
{
date = inputFormat.parse(inputDate);
}
catch (ParseException e)
{
}
SimpleDateFormat outputFormat = new SimpleDateFormat("EEE MMM d HH:mm:ss Z yyyy", Locale.US);
outputFormat.setTimeZone(timeZoneSH);
System.out.println("Asia/Shanghai:" + outputFormat.format(date));
outputFormat.setTimeZone(timeZoneNY);
System.out.println("America/New_York:" + outputFormat.format(date));
那么驰坊,夏令時(DST)的問題怎么解決呢匾二?令人高興的是,JDK(or JRE)已自動為我們進(jìn)行了夏令時處理拳芙〔烀辏可以做個試驗(yàn),來驗(yàn)證以上第2段代碼能適用于夏令時轉(zhuǎn)換舟扎。美國在2011年開始和結(jié)束夏令時的時間是:3.13 2AM和11.6 2AM分飞。
- 將輸入時間inputDate設(shè)置為"2011-03-13 14:59:59",輸出: Asia/Shanghai:Sun Mar 13 14:59:59 +0800 2011 America/New_York:Sun Mar 13 01:59:59 -0500 2011 此時睹限,美國東部時間還差1秒進(jìn)入夏令時譬猫,與北京時間相差13小時讯檐。
- 將輸入時間inputDate設(shè)置為"2011-03-13 15:00:00",輸出: Asia/Shanghai:Sun Mar 13 15:00:00 +0800 2011 America/New_York:Sun Mar 13 03:00:00 -0400 2011 此時染服,美國東部時間剛好進(jìn)入夏令時别洪,與北京時間相差12小時,同時柳刮,所使用的時區(qū)也發(fā)生了變化挖垛。
結(jié)束夏令時的試驗(yàn)就不再贅述了。
JDK(or JRE)之所以能自動的進(jìn)行DST處理诚亚,是因?yàn)槠湟褍?nèi)置了各個國家的夏令時政策晕换,并提供Timezone Updater Tool來保持低版本JDK(or JRE)的TimeZone更新,但SUN官方推薦使用JDK(or JRE)的更新來更新TimeZone信息站宗。
綜上闸准,我們應(yīng)盡量在系統(tǒng)中使用如上描述的long類型變量來記錄時間,借助相應(yīng)的方法梢灭,可方便的格式化為不同時區(qū)的時間進(jìn)行顯示夷家。