好東西分享
日期和時間的處理不僅在面試題中會考到,在實際項目開發(fā)中也是我們經常需要處理的問題,似乎沒有哪個項目可以避開它們,我們常常在處理用戶的出生年月日、注冊日期,訂單的創(chuàng)建時間等屬性時用到,由此可見其重要性。
java.util.Date類
提到日期和時間,我想大家最先想到應該是java.util.Date類吧。Date類可以精確到毫秒數,這個毫秒數是相對于格林威治標準時間“1970-01-01 00:00:00.000 GMT”的差值。那么,什么是格林威治標準時間呢?要回答這個問題,我們需要先來了解一下世界時間標準方面的知識。
世界時間標準主要有UTC,即Coordinated Universal Time(中文名譯作世界協(xié)調時間、世界統(tǒng)一時間或世界標準時間),以及GMT,即Greenwich Mean Time(中文名譯作格林威治標準時間或格林威治平均時間)兩種。嚴格來講,UTC比GMT更加精確一些,不過它們的差值不會超過0.9秒,如果超過了,將會為UTC增加閏秒以與GMT,也就是地球自轉周期保持一致。所以在日常使用中,我們可以把UTC和GMT一樣看待。
日期和時間的表示是與我們所處的時區(qū)相關聯(lián)的,如果我們不指定時區(qū),那么它們將以系統(tǒng)默認的時區(qū)來顯示。我們先來看看如何創(chuàng)建日期對象。Date類有很多個構造器方法,大部分已經不被贊成使用了(Deprecated),不過還剩下兩個可以使用的:
- public ?Date()?{ ??
- ???? this (System.currentTimeMillis()); ??
- } ??
- ??
- public ?Date( long ?date)?{ ??
- ???? //other?code ??
- }??
public Date() { this(System.currentTimeMillis()); } public Date(long date) { //other code }
第一個是無參構造器,使用系統(tǒng)當前時間的毫秒數來創(chuàng)建Date對象,它調用了java.lang.System類的currentTimeMillis()來取得系統(tǒng)的當前時間的毫秒值。這是個本地方法,它的定義如下:
- public ? static ? native ? long ?currentTimeMillis();??
public static native long currentTimeMillis();
第二個構造器是根據給定的毫秒數來創(chuàng)建一個與之對應的Date對象,這個毫秒數決定了被創(chuàng)建對象的年、月、日、時、分、秒屬性的值。
我們來看看日期和時間在默認時區(qū)下的顯示效果:
- import ?java.util.Date; ??
- ??
- public ? class ?DateTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ????????Date?d?=? new ?Date(); ??
- ???????? //?在默認時區(qū)下輸出日期和時間值 ??
- ????????System.out.println(d); ??
- ????} ??
- }??
import java.util.Date; public class DateTest { public static void main(String[] args) { Date d = new Date(); // 在默認時區(qū)下輸出日期和時間值 System.out.println(d); } }
運行結果:
- Tue Jul 22 10:44:47 CST 2008
大家應該注意到了年份前的“CST”標識,它是China Standard Time的縮寫,指的是中國標準時間,也就是我們常說的北京時間。它與UTC的時差是UTC+8:00,就是說北京時間比世界標準時間早8個小時,如果世界標準時間是早上1點,北京時間就是早上9點。一般情況下我們不需要關心時區(qū)問題。
在創(chuàng)建完Date對象之后,我們可以通過調用getTime()方法來獲得該對象的毫秒數值,調用setTime(long time)方法來設置它的毫秒數值,從而影響年、月、日、時、分、秒這些屬性。這兩個方法的定義如下:
- public ? long ?getTime()?{ ??
- ???? //other?code ??
- } ??
- ??
- public ? void ?setTime( long ?time)?{ ??
- ???? //other?code ??
- }??
public long getTime() { //other code } public void setTime(long time) { //other code }
既然Date對象可以表示盛相對于“1970-01-01 00:00:00.000 GMT”的毫秒數,我們自然可以通過這個值來比較兩個日期的大小了,不過對于日期來講,前后的說法應該更為恰當。而Date類已經為我們提供了這樣的方法:
- public ? boolean ?before(Date?when)?{ ??
- ???? //other?code ??
- } ??
- ??
- public ? boolean ?after(Date?when)?{ ??
- ???? //other?code ??
- } ??
- ??
- public ? int ?compareTo(Date?anotherDate)?{ ??
- ???? //other?code ??
- }??
public boolean before(Date when) { //other code } public boolean after(Date when) { //other code } public int compareTo(Date anotherDate) { //other code }
before()是判斷當前日期是否在參數日期之前,即當前日期毫秒數小于參數日期毫秒數;after()是判斷當前日期是否在參數日期之后,即當前日期毫秒數大于參數日期毫秒數。而compareTo()是將當前日期與參數日期比較后,返回一個int型值,它的返回值有三種可能:-1、0和1。如果返回-1則表示當前日期在參數日期之前;如果返回0則表示兩個日期是同一時刻;返回1則表示當前日期在參數日期之后。雖然我們可以用compareTo()方法來比較兩個Date對象,但是它的設計實際是另有用途的,我們在后面的章節(jié)將會講到。
下面我們就用一個示例來檢驗一下以上方法的用法:
- import ?java.util.Date; ??
- ??
- public ? class ?DateTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ???????? //?2008-08-08?20:00:00對應的毫秒數 ??
- ???????? long ?t2008?=?1218196800000L; ??
- ???????? //?1900-01-01?20:00:00對應的毫秒數 ??
- ???????? long ?t1900?=?-2208945952000L; ??
- ??
- ???????? //?指定毫秒數創(chuàng)建Date對象 ??
- ????????Date?d2008?=? new ?Date(t2008); ??
- ???????? //?使用系統(tǒng)默認時間創(chuàng)建Date對象 ??
- ????????Date?d1900?=? new ?Date(); ??
- ???????? //?通過設置毫秒數改變日期和時間 ??
- ????????d1900.setTime(t1900); ??
- ??
- ????????System.out.println( "調用方法:d1900.before(d2008)" ); ??
- ????????System.out ??
- ????????????????.print( "比較結果:\"1900-01-01?20:00:00\"在\"2008-08-08?20:00:00\"" ); ??
- ???????? //?使用before()方法比較 ??
- ???????? if ?(d1900.before(d2008))?{ ??
- ????????????System.out.println( "之前" ); ??
- ????????}? else ?{ ??
- ????????????System.out.println( "之后" ); ??
- ????????} ??
- ???????? ??
- ????????System.out.println(); ??
- ???????? ??
- ????????System.out.println( "調用方法:d2008.after(d1900)" ); ??
- ????????System.out ??
- ????????????????.print( "比較結果:\"2008-08-08?20:00:00\"在\"1900-01-01?20:00:00\"" ); ??
- ???????? //?使用after()方法比較 ??
- ???????? if ?(d2008.after(d1900))?{ ??
- ????????????System.out.println( "之后" ); ??
- ????????}? else ?{ ??
- ????????????System.out.println( "之前" ); ??
- ????????} ??
- ???????? ??
- ????????System.out.println(); ??
- ???????? ??
- ????????System.out.println( "調用方法:d1900.compareTo(d2008)" ); ??
- ????????System.out ??
- ????????????????.print( "比較結果:\"1900-01-01?20:00:00\"在\"2008-08-08?20:00:00\"" ); ??
- ???????? //?使用compareTo()方法比較 ??
- ???????? int ?i?=?d1900.compareTo(d2008); ??
- ???????? if ?(i?==?- 1 )?{ ??
- ????????????System.out.println( "之前" ); ??
- ????????}? else ? if ?(i?==? 1 )?{ ??
- ????????????System.out.println( "之后" ); ??
- ????????}? else ? if ?(i?==? 0 )?{ ??
- ????????????System.out.println( "是同一時刻" ); ??
- ????????} ??
- ????} ??
- }??
import java.util.Date; public class DateTest { public static void main(String[] args) { // 2008-08-08 20:00:00對應的毫秒數 long t2008 = 1218196800000L; // 1900-01-01 20:00:00對應的毫秒數 long t1900 = -2208945952000L; // 指定毫秒數創(chuàng)建Date對象 Date d2008 = new Date(t2008); // 使用系統(tǒng)默認時間創(chuàng)建Date對象 Date d1900 = new Date(); // 通過設置毫秒數改變日期和時間 d1900.setTime(t1900); System.out.println("調用方法:d1900.before(d2008)"); System.out .print("比較結果:\"1900-01-01 20:00:00\"在\"2008-08-08 20:00:00\""); // 使用before()方法比較 if (d1900.before(d2008)) { System.out.println("之前"); } else { System.out.println("之后"); } System.out.println(); System.out.println("調用方法:d2008.after(d1900)"); System.out .print("比較結果:\"2008-08-08 20:00:00\"在\"1900-01-01 20:00:00\""); // 使用after()方法比較 if (d2008.after(d1900)) { System.out.println("之后"); } else { System.out.println("之前"); } System.out.println(); System.out.println("調用方法:d1900.compareTo(d2008)"); System.out .print("比較結果:\"1900-01-01 20:00:00\"在\"2008-08-08 20:00:00\""); // 使用compareTo()方法比較 int i = d1900.compareTo(d2008); if (i == -1) { System.out.println("之前"); } else if (i == 1) { System.out.println("之后"); } else if (i == 0) { System.out.println("是同一時刻"); } } }
運行結果:
- 調用方法:d1900.before(d2008)
- 比較結果:"1900-01-01 20:00:00"在"2008-08-08 20:00:00"之前
- 調用方法:d2008.after(d1900)
- 比較結果:"2008-08-08 20:00:00"在"1900-01-01 20:00:00"之后
- 調用方法:d1900.compareTo(d2008)
- 比較結果:"1900-01-01 20:00:00"在"2008-08-08 20:00:00"之前
那么如果我們想直接獲取或者改變年、月、日、時、分、秒等等這些屬性的值時怎么辦呢?Date類當然有完成這些操作的方法,不過遺憾的是它們也都已經不被贊成使用了。我們必須換一個能夠提供這些操作的類,這個類就是java.util.Calendar。
公歷歷法java.util.GregorianCalendar
Calendar是一個抽象類,我們無法直接實例化它,它有一個具體子類實體類java.util.GregorianCalendar,這個類實現的就是我們日常所用的公歷歷法,或者叫做陽歷。我們可以直接使用new命令創(chuàng)建它的實例,或者使用Calendar類的這個方法來獲得它實例:
- public ? static ?Calendar?getInstance(){ ??
- ???? //other?code ??
- }??
public static Calendar getInstance(){ //other code }
采用上面這個方法時,我們創(chuàng)建的Calendar對象的日期和時間值是對象被創(chuàng)建時系統(tǒng)日期和時間值。當使用new命令時,我們有兩種選擇,一種是使用系統(tǒng)當前的日期和時間值初始化GregorianCalendar對象;另一種是通過給定年、月、日、時、分、秒等屬性值來對其進行初始化。請看下面的例子:
- import ?java.text.DateFormat; ??
- import ?java.text.SimpleDateFormat; ??
- import ?java.util.Calendar; ??
- import ?java.util.GregorianCalendar; ??
- ??
- public ? class ?DateTest?{ ??
- ???? /** ?
- ?????*?以一種較為友好的方式格式化日期時間值 ?
- ?????*? ?
- ?????*?@param?c ?
- ?????*????????????日期時間對象 ?
- ?????*?@return?格式化后的日期時間字符串 ?
- ?????*/ ??
- ???? public ? static ?String?toFriendlyString(Calendar?c)?{ ??
- ???????? if ?(c?!=? null )?{ ??
- ????????????DateFormat?df?=? new ?SimpleDateFormat( "yyyy年MM月dd日?HH:mm:ss" ); ??
- ???????????? return ?df.format(c.getTime()); ??
- ????????} ??
- ???????? return ? null ; ??
- ????} ??
- ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ????????Calendar?c1?=?Calendar.getInstance(); ??
- ????????System.out.println( "創(chuàng)建方式:Calendar.getInstance()" ); ??
- ????????System.out.println( "日期時間:" ?+?DateTest.toFriendlyString(c1)); ??
- ????????System.out.println(); ??
- ??
- ????????Calendar?c2?=? new ?GregorianCalendar(); ??
- ????????System.out.println( "創(chuàng)建方式:new?GregorianCalendar()" ); ??
- ????????System.out.println( "日期時間:" ?+?DateTest.toFriendlyString(c2)); ??
- ????????System.out.println(); ??
- ??
- ???????? //?參數含義依次為:年、月、日 ??
- ????????Calendar?c3?=? new ?GregorianCalendar( 2008 ,? 8 ,? 8 ); ??
- ????????System.out.println( "創(chuàng)建方式:new?GregorianCalendar(2008,?8,?8)" ); ??
- ????????System.out.println( "日期時間:" ?+?DateTest.toFriendlyString(c3)); ??
- ????????System.out.println(); ??
- ??
- ???????? //?參數含義依次為:年、月、日、時、分 ??
- ????????Calendar?c4?=? new ?GregorianCalendar( 2008 ,? 8 ,? 8 ,? 6 ,? 10 ); ??
- ????????System.out.println( "創(chuàng)建方式:new?GregorianCalendar(2008,?8,?8,?6,?10)" ); ??
- ????????System.out.println( "日期時間:" ?+?DateTest.toFriendlyString(c4)); ??
- ????????System.out.println(); ??
- ??
- ???????? //?參數含義依次為:年、月、日、時、分、秒 ??
- ????????Calendar?c5?=? new ?GregorianCalendar( 2008 ,? 8 ,? 8 ,? 18 ,? 10 ,? 5 ); ??
- ????????System.out.println( "創(chuàng)建方式:new?GregorianCalendar(2008,?8,?8,?18,?10,?5)" ); ??
- ????????System.out.println( "日期時間:" ?+?DateTest.toFriendlyString(c5)); ??
- ????} ??
- }??
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; public class DateTest { /** * 以一種較為友好的方式格式化日期時間值 * * @param c * 日期時間對象 * @return 格式化后的日期時間字符串 */ public static String toFriendlyString(Calendar c) { if (c != null) { DateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); return df.format(c.getTime()); } return null; } public static void main(String[] args) { Calendar c1 = Calendar.getInstance(); System.out.println("創(chuàng)建方式:Calendar.getInstance()"); System.out.println("日期時間:" + DateTest.toFriendlyString(c1)); System.out.println(); Calendar c2 = new GregorianCalendar(); System.out.println("創(chuàng)建方式:new GregorianCalendar()"); System.out.println("日期時間:" + DateTest.toFriendlyString(c2)); System.out.println(); // 參數含義依次為:年、月、日 Calendar c3 = new GregorianCalendar(2008, 8, 8); System.out.println("創(chuàng)建方式:new GregorianCalendar(2008, 8, 8)"); System.out.println("日期時間:" + DateTest.toFriendlyString(c3)); System.out.println(); // 參數含義依次為:年、月、日、時、分 Calendar c4 = new GregorianCalendar(2008, 8, 8, 6, 10); System.out.println("創(chuàng)建方式:new GregorianCalendar(2008, 8, 8, 6, 10)"); System.out.println("日期時間:" + DateTest.toFriendlyString(c4)); System.out.println(); // 參數含義依次為:年、月、日、時、分、秒 Calendar c5 = new GregorianCalendar(2008, 8, 8, 18, 10, 5); System.out.println("創(chuàng)建方式:new GregorianCalendar(2008, 8, 8, 18, 10, 5)"); System.out.println("日期時間:" + DateTest.toFriendlyString(c5)); } }
運行結果如下:
- 創(chuàng)建方式:Calendar.getInstance()
- 日期時間:2008年07月22日 11:54:48
- 創(chuàng)建方式:new GregorianCalendar()
- 日期時間:2008年07月22日 11:54:48
-
創(chuàng)建方式:new GregorianCalendar(2008, 8,
- 日期時間:2008年09月08日 00:00:00
- 創(chuàng)建方式:new GregorianCalendar(2008, 8, 8, 6, 10)
- 日期時間:2008年09月08日 06:10:00
- 創(chuàng)建方式:new GregorianCalendar(2008, 8, 8, 18, 10, 5)
- 日期時間:2008年09月08日 18:10:05
為了便于閱讀,我們增加一個toFriendlyString(Calendar c)方法,它將日期時間值格式化為一種更加友好易懂的形式,我們將在接下來的內容中講解它的實現原理。分析運行結果后,我們發(fā)現有兩個地方需要注意:
- 在創(chuàng)建GregorianCalendar對象時,月份值都設定為8,但打印結果都是9月份。這并不是我們的代碼有問題,而是因為JAVA表示的月份是從0開始的,也就是說它用來表示月份的數值總是比實際月份值小1。因此我們要表示8月份,就是應該設置8-1=7這個值。
- GregorianCalendar的小時數是24小時制的。
為了避免出現因為忘記處理1的差值而設置了錯誤的月份,也讓代碼看起來更加直觀,推薦大家使用定義在Calendar類的的這些常量來代替直接用數字表示月份:
- 一月:Calendar.JANUARY = 0
- 二月:Calendar.FEBRUARY = 1
- 三月:Calendar.MARCH = 2
- 四月:Calendar.APRIL = 3
- 五月:Calendar.MAY = 4
- 六月:Calendar.JUNE = 5
- 七月:Calendar.JULY = 6
- 八月:Calendar.AUGUST = 7
- 九月:Calendar.SEPTEMBER = 8
- 十月:Calendar.OCTOBER = 9
- 十一月:Calendar.NOVEMBER = 10
- 十二月:Calendar.DECEMBER = 11
如果我們想要從Calendar對象獲得各種屬性的值,就需要調用它的get(int field)方法,這個方法接收一個int型的參數,并且根據這個給定參數的值來返回相應的屬性的值。該方法的定義如下:
- public ? int ?get( int ?field){ ??
- ???? //other?code ??
- }??
public int get(int field){ //other code }
我們以一個示例來說明get(int field)方法所能接受的一些常用參數的含義及用法:
- import ?java.text.DateFormat; ??
- import ?java.text.SimpleDateFormat; ??
- import ?java.util.Calendar; ??
- ??
- public ? class ?DateTest?{ ??
- ???? /** ?
- ?????*?以一種較為友好的方式格式化日期時間值 ?
- ?????*? ?
- ?????*?@param?c ?
- ?????*????????????日期時間對象 ?
- ?????*?@return?格式化后的日期時間字符串 ?
- ?????*/ ??
- ???? public ? static ?String?toFriendlyString(Calendar?c)?{ ??
- ???????? if ?(c?!=? null )?{ ??
- ????????????DateFormat?df?=? new ?SimpleDateFormat( "yyyy年MM月dd日?HH:mm:ss.SSS" ); ??
- ???????????? return ?df.format(c.getTime()); ??
- ????????} ??
- ???????? return ? null ; ??
- ????} ??
- ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ????????Calendar?c?=?Calendar.getInstance(); ??
- ????????System.out.println( "當前時刻:" ?+?DateTest.toFriendlyString(c)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.AM_PM" ); ??
- ????????System.out.println( "代表含義:上下午標識,上午返回Calendar.AM=0,下午返回Calendar.PM=1" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.AM_PM)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.DATE" ); ??
- ????????System.out.println( "代表含義:一個月中的第幾天,同Calendar.DAY_OF_MONTH" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.DATE)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.DAY_OF_MONTH" ); ??
- ????????System.out.println( "代表含義:一個月中的第幾天,同Calendar.DATE" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.DAY_OF_MONTH)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.DAY_OF_WEEK" ); ??
- ????????System.out.println( "代表含義:一周中的第幾天,對應星期幾,第一天為星期日,于此類推。" ); ??
- ????????System.out.println( "星期日:Calendar.SUNDAY=1" ); ??
- ????????System.out.println( "星期一:Calendar.MONDAY=2" ); ??
- ????????System.out.println( "星期二:Calendar.TUESDAY=3" ); ??
- ????????System.out.println( "星期三:Calendar.WEDNESDAY=4" ); ??
- ????????System.out.println( "星期四:Calendar.THURSDAY=5" ); ??
- ????????System.out.println( "星期五:Calendar.FRIDAY=6" ); ??
- ????????System.out.println( "星期六:Calendar.SATURDAY=7" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.DAY_OF_WEEK)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.DAY_OF_WEEK_IN_MONTH" ); ??
- ????????System.out.println( "代表含義:這一天所對應的星期幾在該月中是第幾次出現" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.DAY_OF_WEEK_IN_MONTH)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.DAY_OF_YEAR" ); ??
- ????????System.out.println( "代表含義:一年中的第幾天" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.DAY_OF_YEAR)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.HOUR" ); ??
- ????????System.out.println( "代表含義:12小時制下的小時數,中午和午夜表示為0" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.HOUR)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.HOUR_OF_DAY" ); ??
- ????????System.out.println( "代表含義:24小時制下的小時數,午夜表示為0" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.HOUR_OF_DAY)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.MILLISECOND" ); ??
- ????????System.out.println( "代表含義:毫秒數" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.MILLISECOND)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.MINUTE" ); ??
- ????????System.out.println( "代表含義:分鐘" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.MINUTE)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.MONTH" ); ??
- ????????System.out.println( "代表含義:月份,從0到11表示12個月份,比實際月份值小1" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.MONTH)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.SECOND" ); ??
- ????????System.out.println( "代表含義:秒" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.SECOND)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.WEEK_OF_MONTH" ); ??
- ????????System.out.println( "代表含義:一個月中的第幾個星期" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.WEEK_OF_MONTH)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.WEEK_OF_YEAR" ); ??
- ????????System.out.println( "代表含義:一年中的第幾個星期" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.WEEK_OF_YEAR)); ??
- ????????System.out.println(); ??
- ??
- ????????System.out.println( "屬性名稱:Calendar.YEAR" ); ??
- ????????System.out.println( "代表含義:年份" ); ??
- ????????System.out.println( "測試結果:" ?+?c.get(Calendar.YEAR)); ??
- ????} ??
- }??
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; public class DateTest { /** * 以一種較為友好的方式格式化日期時間值 * * @param c * 日期時間對象 * @return 格式化后的日期時間字符串 */ public static String toFriendlyString(Calendar c) { if (c != null) { DateFormat df = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss.SSS"); return df.format(c.getTime()); } return null; } public static void main(String[] args) { Calendar c = Calendar.getInstance(); System.out.println("當前時刻:" + DateTest.toFriendlyString(c)); System.out.println(); System.out.println("屬性名稱:Calendar.AM_PM"); System.out.println("代表含義:上下午標識,上午返回Calendar.AM=0,下午返回Calendar.PM=1"); System.out.println("測試結果:" + c.get(Calendar.AM_PM)); System.out.println(); System.out.println("屬性名稱:Calendar.DATE"); System.out.println("代表含義:一個月中的第幾天,同Calendar.DAY_OF_MONTH"); System.out.println("測試結果:" + c.get(Calendar.DATE)); System.out.println(); System.out.println("屬性名稱:Calendar.DAY_OF_MONTH"); System.out.println("代表含義:一個月中的第幾天,同Calendar.DATE"); System.out.println("測試結果:" + c.get(Calendar.DAY_OF_MONTH)); System.out.println(); System.out.println("屬性名稱:Calendar.DAY_OF_WEEK"); System.out.println("代表含義:一周中的第幾天,對應星期幾,第一天為星期日,于此類推。"); System.out.println("星期日:Calendar.SUNDAY=1"); System.out.println("星期一:Calendar.MONDAY=2"); System.out.println("星期二:Calendar.TUESDAY=3"); System.out.println("星期三:Calendar.WEDNESDAY=4"); System.out.println("星期四:Calendar.THURSDAY=5"); System.out.println("星期五:Calendar.FRIDAY=6"); System.out.println("星期六:Calendar.SATURDAY=7"); System.out.println("測試結果:" + c.get(Calendar.DAY_OF_WEEK)); System.out.println(); System.out.println("屬性名稱:Calendar.DAY_OF_WEEK_IN_MONTH"); System.out.println("代表含義:這一天所對應的星期幾在該月中是第幾次出現"); System.out.println("測試結果:" + c.get(Calendar.DAY_OF_WEEK_IN_MONTH)); System.out.println(); System.out.println("屬性名稱:Calendar.DAY_OF_YEAR"); System.out.println("代表含義:一年中的第幾天"); System.out.println("測試結果:" + c.get(Calendar.DAY_OF_YEAR)); System.out.println(); System.out.println("屬性名稱:Calendar.HOUR"); System.out.println("代表含義:12小時制下的小時數,中午和午夜表示為0"); System.out.println("測試結果:" + c.get(Calendar.HOUR)); System.out.println(); System.out.println("屬性名稱:Calendar.HOUR_OF_DAY"); System.out.println("代表含義:24小時制下的小時數,午夜表示為0"); System.out.println("測試結果:" + c.get(Calendar.HOUR_OF_DAY)); System.out.println(); System.out.println("屬性名稱:Calendar.MILLISECOND"); System.out.println("代表含義:毫秒數"); System.out.println("測試結果:" + c.get(Calendar.MILLISECOND)); System.out.println(); System.out.println("屬性名稱:Calendar.MINUTE"); System.out.println("代表含義:分鐘"); System.out.println("測試結果:" + c.get(Calendar.MINUTE)); System.out.println(); System.out.println("屬性名稱:Calendar.MONTH"); System.out.println("代表含義:月份,從0到11表示12個月份,比實際月份值小1"); System.out.println("測試結果:" + c.get(Calendar.MONTH)); System.out.println(); System.out.println("屬性名稱:Calendar.SECOND"); System.out.println("代表含義:秒"); System.out.println("測試結果:" + c.get(Calendar.SECOND)); System.out.println(); System.out.println("屬性名稱:Calendar.WEEK_OF_MONTH"); System.out.println("代表含義:一個月中的第幾個星期"); System.out.println("測試結果:" + c.get(Calendar.WEEK_OF_MONTH)); System.out.println(); System.out.println("屬性名稱:Calendar.WEEK_OF_YEAR"); System.out.println("代表含義:一年中的第幾個星期"); System.out.println("測試結果:" + c.get(Calendar.WEEK_OF_YEAR)); System.out.println(); System.out.println("屬性名稱:Calendar.YEAR"); System.out.println("代表含義:年份"); System.out.println("測試結果:" + c.get(Calendar.YEAR)); } }
運行結果如下:
- 當前時刻:2008年07月22日 13:16:07.421
- 屬性名稱:Calendar.AM_PM
- 代表含義:上下午標識,上午返回Calendar.AM=0,下午返回Calendar.PM=1
- 測試結果:1
- 屬性名稱:Calendar.DATE
- 代表含義:一個月中的第幾天,同Calendar.DAY_OF_MONTH
- 測試結果:22
- 屬性名稱:Calendar.DAY_OF_MONTH
- 代表含義:一個月中的第幾天,同Calendar.DATE
- 測試結果:22
- 屬性名稱:Calendar.DAY_OF_WEEK
- 代表含義:一周中的第幾天,對應星期幾,第一天為星期日,于此類推。
- 星期日:Calendar.SUNDAY=1
- 星期一:Calendar.MONDAY=2
- 星期二:Calendar.TUESDAY=3
- 星期三:Calendar.WEDNESDAY=4
- 星期四:Calendar.THURSDAY=5
- 星期五:Calendar.FRIDAY=6
- 星期六:Calendar.SATURDAY=7
- 測試結果:3
- 屬性名稱:Calendar.DAY_OF_WEEK_IN_MONTH
- 代表含義:這一天所對應的星期幾在該月中是第幾次出現
- 測試結果:4
- 屬性名稱:Calendar.DAY_OF_YEAR
- 代表含義:一年中的第幾天
- 測試結果:204
- 屬性名稱:Calendar.HOUR
- 代表含義:12小時制下的小時數,中午和午夜表示為0
- 測試結果:1
- 屬性名稱:Calendar.HOUR_OF_DAY
- 代表含義:24小時制下的小時數,午夜表示為0
- 測試結果:13
- 屬性名稱:Calendar.MILLISECOND
- 代表含義:毫秒數
- 測試結果:421
- 屬性名稱:Calendar.MINUTE
- 代表含義:分鐘
- 測試結果:16
- 屬性名稱:Calendar.MONTH
- 代表含義:月份,從0到11表示12個月份,比實際月份值小1
- 測試結果:6
- 屬性名稱:Calendar.SECOND
- 代表含義:秒
- 測試結果:7
- 屬性名稱:Calendar.WEEK_OF_MONTH
- 代表含義:一個月中的第幾個星期
- 測試結果:4
- 屬性名稱:Calendar.WEEK_OF_YEAR
- 代表含義:一年中的第幾個星期
- 測試結果:30
- 屬性名稱:Calendar.YEAR
- 代表含義:年份
- 測試結果:2008
其中Calendar.DAY_OF_WEEK_IN_MONTH代表的含義比較難理解一些,它表示“這一天所對應的星期幾在該月中是第幾次出現”。比如2008年8月8日是星期五,在它之前的8月1日也是星期五,因此它是8月份的第二個星期五。所以這時調用get(Calendar.DAY_OF_WEEK_IN_MONTH)就會返回2。這里存在一個簡單易記的規(guī)律:對于每月的1-7號,它們一定占全了星期一到星期日,所以不管是它們中的哪一天,也不管這一天是星期幾,它總是第一個,因此返回1;8-14號也同樣占全了星期一到星期日,但由于1-7號的關系,對于它們總是返回2;以此類推,15-21號返回3,22-28號返回4,29-31號返回5。
Calendar對象和Date對象可以通過Calendar類的如下兩個方法進行相互轉換:
- public ? final ?Date?getTime()?{ ??
- ???? //other?code ??
- } ??
- ??
- public ? final ? void ?setTime(Date?date)?{ ??
- ???? //other?code ??
- }??
public final Date getTime() { //other code } public final void setTime(Date date) { //other code }
日期格式化與解析
我們回頭再來看看在上面的例子中定義的toFriendlyString(Calendar c)方法,它將一個Calendar對象的日期時間值以一種很友好的方式來展現,使人們很容易看懂,也符合我們中國人的習慣。這完全得益于抽象類DateFormat以及它的子類實體類SimpleDateFormat的幫助。這兩個類都位于java.text包中,是專門用于日期格式化和解析的類。而這兩項工作的核心就是我們?yōu)榇嗽O定的Pattern,我們可以稱之為“日期格式表達式”。
理論上講日期格式表達式包含全部26個英文字母的大小寫,不過它們中的一些字母只是被預留了,并沒有確切的含義。目前有效的字母及它們所代表的含義如下:
- G:年代標識,表示是公元前還是公元后
- y:年份
- M:月份
- d:日
- h:小時,從1到12,分上下午
- H:小時,從0到23
- m:分鐘
- s:秒
- S:毫秒
- E:一周中的第幾天,對應星期幾,第一天為星期日,于此類推???
- z:時區(qū)
- D:一年中的第幾天
- F:這一天所對應的星期幾在該月中是第幾次出現
- w:一年中的第幾個星期
- W:一個月中的第幾個星期
- a:上午/下午標識
- k:小時,從1到24
- K:小時,從0到11,區(qū)分上下午
在日期格式表達式中出現的所有字母,在進行日期格式化操作后,都將被其所代表的含義對應的屬性值所替換,并且對某些字母來說,重復次數的不同,格式化后的結果也會有所不同。請看下面的例子:
- import ?java.text.SimpleDateFormat; ??
- import ?java.util.Date; ??
- ??
- public ? class ?DateTest?{ ??
- ???? public ? static ? void ?main(String[]?args)?{ ??
- ???????? //?使用系統(tǒng)當前日期時間值創(chuàng)建一個Date對象 ??
- ????????Date?now?=? new ?Date(); ??
- ??
- ???????? //?創(chuàng)建一個日期格式表達式 ??
- ????????String?pattern?=? "年代:G;年份:y;月份:M;日:d;時(1~12):h;時(0~23):H;分:m;秒:s;毫秒:S;星期:E;上/下午:a;時區(qū):z" ; ??
- ???????? <span
發(fā)表評論
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

評論