1.java.util.Calendar
Calendar 類是一個抽象類,它為特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日歷字段之間的轉(zhuǎn)換提供了一些方法,并為操作日歷字段(例如獲得下星期的日期)提供了一些方法。瞬間可用毫秒值來表示,它是距歷元(即格林威治標準時間 1970 年 1 月 1 日的 00:00:00.000,格里高利歷)的偏移量。
例:
Calendar cal = Calendar.getInstance();//使用默認時區(qū)和語言環(huán)境獲得一個日歷。
cal.add(Calendar.DAY_OF_MONTH, -1);//取當前日期的前一天.
cal.add(Calendar.DAY_OF_MONTH, +1);//取當前日期的后一天.
//通過格式化輸出日期
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
System.out.println("Today is:"+format.format(Calendar.getInstance().getTime()));
System.out.println("yesterday is:"+format.format(cal.getTime()));
//得到2007-12-25日期:
Calendar calendar = new GregorianCalendar(2007, 11, 25,0,0,0);
Date date = calendar.getTime();
System.out.println("2007 Christmas is:"+format.format(date));
//GregorianCalendar構(gòu)造方法參數(shù)依次為:年,月-1,日,時,分,秒.
//java月份是從0-11,月份設(shè)置時要減1,取月份要加1.
取日期的部分:
int year =calendar.get(Calendar.YEAR);
int month=calendar.get(Calendar.MONTH)+1;
int day =calendar.get(Calendar.DAY_OF_MONTH);
int hour =calendar.get(Calendar.HOUR_OF_DAY);
int minute =calendar.get(Calendar.MINUTE);
int seconds =calendar.get(Calendar.SECOND);
判斷當前月份的最大天數(shù):
Calendar cal = Calendar.getInstance();
int day=cal.getActualMaximum(Calendar.DAY_OF_MONTH);
System.out.println(day);
2. java.util.Date
類 Date 表示特定的瞬間,精確到毫秒。從 JDK 1.1 開始,應(yīng)該使用 Calendar 類實現(xiàn)日期和時間字段之間轉(zhuǎn)換,使用 DateFormat 類來格式化和分析日期字符串。Date 中的相應(yīng)方法已廢棄。
盡管 Date 類打算反映協(xié)調(diào)世界時 (UTC),但無法做到如此準確,這取決于 Java 虛擬機的主機環(huán)境。當前幾乎所有操作系統(tǒng)都假定 1 天 = 24 × 60 × 60 = 86400 秒。但對于 UTC,大約每一兩年出現(xiàn)一次額外的一秒,稱為“閏秒”。閏秒始終作為當天的最后一秒增加,并且始終在 12 月 31 日或 6 月 30 日增加。例如,1995 年的最后一分鐘是 61 秒,因為增加了閏秒。大多數(shù)計算機時鐘不是特別的準確,因此不能反映閏秒的差別。
一些計算機標準是按照格林威治標準時 (GMT) 定義的,格林威治標準時和世界時 (UT) 是相等的。GMT 是標準的“民間”名稱;UT 是相同標準的“科學(xué)”名稱。UTC 和 UT 的區(qū)別是:UTC 是基于原子時鐘的,UT 是基于天體觀察的,兩者在實際應(yīng)用中難分軒輊。因為地球的旋轉(zhuǎn)不是均勻的(它以復(fù)雜的方式減速和加速),所以 UT 始終不是均勻地流過。閏秒是根據(jù)需要引入 UTC 的,以便把 UTC 保持在 UT1 的 0.9 秒之內(nèi),UT1 是應(yīng)用了某些更正的 UT 版本。還有其他的時間和日期系統(tǒng);例如,基于衛(wèi)星的全球定位系統(tǒng) (GPS) 使用的時間刻度與 UTC 同步,但沒有針對閏秒進行調(diào)整。有關(guān)更多信息的一個有趣來源是美國海軍天文臺,特別是 Directorate of Time 的網(wǎng)址:
http://tycho.usno.navy.mil。還有它們對 "Systems of Time" 的定義,網(wǎng)址為:http://tycho.usno.navy.mil/systime.html
在類 Date 所有可以接受或返回年、月、日期、小時、分鐘和秒值的方法中,將使用下面的表示形式:
年份 y 由整數(shù) y – 1900 表示。
月份由從 0 至 11 的整數(shù)表示;0 是一月、1 是二月等等;因此 11 是十二月。
日期(一月中的某天)按通常方式由整數(shù) 1 至 31 表示。
小時由從 0 至 23 的整數(shù)表示。因此,從午夜到 1 a.m. 的時間是 0 點,從中午到 1 p.m. 的時間是 12 點。
分鐘按通常方式由 0 至 59 的整數(shù)表示。
秒由 0 至 61 的整數(shù)表示;值 60 和 61 只對閏秒發(fā)生,盡管那樣,也只用在實際正確跟蹤閏秒的 Java 實現(xiàn)中。于按當前引入閏秒的方式,兩個閏秒在同一分鐘內(nèi)發(fā)生是極不可能的,但此規(guī)范遵循 ISO C 的日期和時間約定。
在所有情形中,針對這些目的賦予方法的參數(shù)不需要在指定的范圍內(nèi);例如,可以把日期指定為 1 月 32 日,并把它解釋為 2 月 1 日的相同含義。
java.util.Date today=new java.util.Date();
System.out.println("Today is "+formats.format(today));
取當月的第一天:
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-01");
java.util.Date firstDay=new java.util.Date();
System.out.println("the month first day is "+formats.format(firstDay));
取當月的最后一天:
Calendar cal = Calendar.getInstance();
int maxDay=cals.getActualMaximum(Calendar.DAY_OF_MONTH);
java.text.Format formatter3=new java.text.SimpleDateFormat("yyyy-MM-"+maxDay);
System.out.println(formatter3.format(cal.getTime()));
求兩個日期之間相隔的天數(shù):
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date beginDate= format.parse("2007-12-24");
java.util.Date endDate= format.parse("2007-12-25");
long day=(date.getTime()-mydate.getTime())/(24*60*60*1000);
System.out.println("相隔的天數(shù)="+day);
一年前的日期:
java.text.Format formatter=new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date todayDate=new java.util.Date();
long beforeTime=(todayDate.getTime()/1000)-60*60*24*365;
todayDate.setTime(beforeTime*1000);
String beforeDate=formatter.format(todayDate);
System.out.println(beforeDate);
一年后的日期:
java.text.Format formatter=new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date todayDate=new java.util.Date();
long afterTime=(todayDate.getTime()/1000)+60*60*24*365;
todayDate.setTime(afterTime*1000);
String afterDate=formatter.format(todayDate);
System.out.println(afterDate);
求10小時后的時間
java.util.Calendar Cal=java.util.Calendar.getInstance();
Cal.setTime(dateOper);
Cal.add(java.util.Calendar.HOUR_OF_DAY,10);
System.out.println("date:"+forma.format(Cal.getTime()));
求10小時前的時間
java.util.Calendar Cal=java.util.Calendar.getInstance();
Cal.setTime(dateOper);
Cal.add(java.util.Calendar.HOUR_OF_DAY,-10);
System.out.println("date:"+forma.format(Cal.getTime()));
3.java.sql.Date
繼承自java.util.Date,是操作數(shù)據(jù)庫用的日期類型
一個包裝了毫秒值的瘦包裝器 (thin wrapper),它允許 JDBC 將毫秒值標識為 SQL DATE 值。毫秒值表示自 1970 年 1 月 1 日 00:00:00 GMT 以來經(jīng)過的毫秒數(shù)。為了與 SQL DATE 的定義一致,由 java.sql.Date 實例包裝的毫秒值必須通過將時間、分鐘、秒和毫秒設(shè)置為與該實例相關(guān)的特定時區(qū)中的零來“規(guī)范化”。
java.sql.Date sqlDate = new java.sql.Date(java.sql.Date.valueOf("2007-12-25").getTime());
日期比較:簡單的比較可以以字符串的形式直接比較,也可使用
java.sql.Date.valueOf("2007-03-08").compareTo(java.sql.Date.valueOf("2007-03-18")) 方式來比較日期的大小.也可使用java.util.Date.after(java.util.Date)來比較.
4.java.util.GregorianCalendar
GregorianCalendar 是 Calendar 的一個具體子類,提供了世界上大多數(shù)國家/地區(qū)使用的標準日歷系統(tǒng)。
GregorianCalendar 是一種混合日歷,在單一間斷性的支持下同時支持儒略歷和格里高利歷系統(tǒng),在默認情況下,它對應(yīng)格里高利日歷創(chuàng)立時的格里高利歷日期(某些國家/地區(qū)是在 1582 年 10 月 15 日創(chuàng)立,在其他國家/地區(qū)要晚一些)。可由調(diào)用方通過調(diào)用 setGregorianChange() 來更改起始日期。
歷史上,在那些首先采用格里高利歷的國家/地區(qū)中,1582 年 10 月 4 日(儒略歷)之后就是 1582 年 10 月 15 日(格里高利歷)。此日歷正確地模擬了這些變化。在開始格里高利歷之前,GregorianCalendar 實現(xiàn)的是儒略歷。格里高利歷和儒略歷之間的惟一區(qū)別就是閏年規(guī)則。儒略歷指定每 4 年就為閏年,而格里高利歷則忽略不能被 400 整除的世紀年。
GregorianCalendar 可實現(xiàn)預(yù)期的格里高利歷和儒略歷。也就是說,可以通過在時間上無限地向后或向前外推當前規(guī)則來計算日期。因此,對于所有的年份,都可以使用 GregorianCalendar 來生成有意義并且一致的結(jié)果。但是,采用現(xiàn)代儒略歷規(guī)則時,使用 GregorianCalendar 得到的日期只在歷史上從公元 4 年 3 月 1 日之后是準確的。在此日期之前,閏年規(guī)則的應(yīng)用沒有規(guī)則性,在 45 BC 之前,甚至不存在儒略歷。
在格里高利歷創(chuàng)立以前,新年是 3 月 25 日。為了避免混淆,此日歷始終使用 1 月 1 日為新年。如果想要格里高利歷轉(zhuǎn)換之前并且處于 1 月 1 日和 3 月 24 日之間的日期,則可以進行手動調(diào)整。
為 WEEK_OF_YEAR 字段所計算的值的范圍從 1 到 53。一年的第一個星期始于 getFirstDayOfWeek() 的最早 7 天,至少包含該年的 getMinimalDaysInFirstWeek() 各天。這取決于 getMinimalDaysInFirstWeek()、getFirstDayOfWeek() 的值以及 1 月 1 日是星期幾。一年的第一個星期和下一年的第一個星期之間的各個星期按順序從 2 到 52 或 53(根據(jù)需要)進行編號。
例如,1998 年 1 月 1 日是星期四。如果 getFirstDayOfWeek() 為 MONDAY,并且 getMinimalDaysInFirstWeek() 為 4(這些值反映了 ISO 8601 和很多國家/地區(qū)標準),則 1998 年的第一個星期開始于 1997 年 12 月 29 日,結(jié)束于 1998 年 1 月 4 日。但是,如果 getFirstDayOfWeek() 為 SUNDAY,那么 1998 年的第一個星期開始于 1998 年 1 月 4 日,結(jié)束于 1998 年 1 月 10 日;1998 年頭三天是 1997 年第 53 個星期的一部分。
為 WEEK_OF_MONTH 字段所計算的值的范圍從 0 到 6。一個月的第一個星期(WEEK_OF_MONTH = 1 的日期)是該月至少連續(xù) getMinimalDaysInFirstWeek() 天中的最早日期,結(jié)束于 getFirstDayOfWeek() 的前一天。與一年的第一個星期不同,一個月的第一個星期可能短于 7 天,也不必從 getFirstDayOfWeek() 這一天開始,并且不包括前一個月的日期。在第一個星期之前該月日期的 WEEK_OF_MONTH 為 0。
5. java.text.DateFormat
DateFormat 是日期/時間格式化子類的抽象類,它以與語言無關(guān)的方式格式化并分析日期或時間。日期/時間格式化子類(如 SimpleDateFormat)允許進行格式化(也就是日期 -> 文本)、分析(文本-> 日期)和標準化。將日期表示為 Date 對象,或者表示為從 GMT(格林尼治標準時間)1970 年,1 月 1 日 00:00:00 這一刻開始的毫秒數(shù)。
DateFormat 提供了很多類方法,以獲得基于默認或給定語言環(huán)境和多種格式化風(fēng)格的默認日期/時間 Formatter。格式化風(fēng)格包括 FULL、LONG、MEDIUM 和 SHORT。方法描述中提供了使用這些風(fēng)格的更多細節(jié)和示例。
DateFormat 可幫助進行格式化并分析任何語言環(huán)境的日期。對于月、星期,甚至日歷格式(陰歷和陽歷),其代碼可完全與語言環(huán)境的約定無關(guān)。
要格式化一個當前語言環(huán)境下的日期,可使用某個靜態(tài)工廠方法:
myString = DateFormat.getDateInstance().format(myDate);
如果格式化多個日期,那么獲得該格式并多次使用它是更為高效的做法,這樣系統(tǒng)就不必多次獲取有關(guān)環(huán)境語言和國家/地區(qū)約定的信息了。
DateFormat df = DateFormat.getDateInstance();
for (int i = 0; i < myDate.length; ++i) {
output.println(df.format(myDate[i]) + "; ");
}
要格式化不同語言環(huán)境的日期,可在 getDateInstance() 的調(diào)用中指定它。
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
還可使用 DateFormat 進行分析:myDate = df.parse(myString);
使用 getDateInstance 來獲得該國家/地區(qū)的標準日期格式。另外還提供了一些其他靜態(tài)工廠方法。使用 getTimeInstance 可獲得該國家/地區(qū)的時間格式。使用 getDateTimeInstance 可獲得日期和時間格式。可以將不同選項傳入這些工廠方法,以控制結(jié)果的長度(從 SHORT 到 MEDIUM 到 LONG 再到 FULL)。確切的結(jié)果取決于語言環(huán)境,但是通常:
SHORT 完全為數(shù)字,如 12.13.52 或 3:30pm
MEDIUM 較長,如 Jan 12, 1952
LONG 更長,如 January 12, 1952 或 3:30:32pm
FULL 是完全指定,如 Tuesday, April 12, 1952 AD 或 3:30:42pm PST。
如果愿意,還可以在格式上設(shè)置時區(qū)。如果想對格式化或分析施加更多的控制(或者給予用戶更多的控制),可以嘗試將從工廠方法所獲得的 DateFormat 強制轉(zhuǎn)換為 SimpleDateFormat。這適用于大多數(shù)國家/地區(qū);只是要記住將其放入一個 try 代碼塊中,以防遇到特殊的格式。
還可以使用借助 ParsePosition 和 FieldPosition 的分析和格式化方法形式來
逐步地分析字符串的各部分。
對齊任意特定的字段,或者找出字符串在屏幕上的選擇位置。
6. java.text.SimpleDateFormat
SimpleDateFormat 是一個以與語言環(huán)境相關(guān)的方式來格式化和分析日期的具體類。它允許進行格式化(日期 -> 文本)、分析(文本 -> 日期)和規(guī)范化。
SimpleDateFormat 使得可以選擇任何用戶定義的日期-時間格式的模式。但是,仍然建議通過 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 來新的創(chuàng)建日期-時間格式化程序。每一個這樣的類方法都能夠返回一個以默認格式模式初始化的日期/時間格式化程序。可以根據(jù)需要使用 applyPattern 方法來修改格式模式。有關(guān)使用這些方法的更多信息,請參閱 DateFormat。
日期和時間模式
日期和時間格式由日期和時間模式 字符串指定。在日期和時間模式字符串中,未加引號的字母 ‘A’ 到 ‘Z’ 和 ‘a’ 到 ‘z’ 被解釋為模式字母,用來表示日期或時間字符串元素。文本可以使用單引號 (’) 引起來,以免進行解釋。"”" 表示單引號。所有其他字符均不解釋;只是在格式化時將它們簡單復(fù)制到輸出字符串,或者在分析時與輸入字符串進行匹配。
定義了以下模式字母(所有其他字符 ‘A’ 到 ‘Z’ 和 ‘a’ 到 ‘z’ 都被保留):
字母
日期或時間元素
表示
示例
G
Era 標志符
Text
AD
y
年
Year
1996; 96
M
年中的月份
Month
July; Jul; 07
w
年中的周數(shù)
Number
27
W
月份中的周數(shù)
Number
2
D
年中的天數(shù)
Number
189
d
月份中的天數(shù)
Number
10
F
月份中的星期
Number
2
E
星期中的天數(shù)
Text
Tuesday; Tue
a
Am/pm 標記
Text
PM
H
一天中的小時數(shù)(0-23)
Number
0
k
一天中的小時數(shù)(1-24)
Number
24
K
am/pm 中的小時數(shù)(0-11)
Number
0
h
am/pm 中的小時數(shù)(1-12)
Number
12
m
小時中的分鐘數(shù)
Number
30
s
分鐘中的秒數(shù)
Number
55
S
毫秒數(shù)
Number
978
z
時區(qū)
General time zone
Pacific Standard Time; PST; GMT-08:00
Z
時區(qū)
RFC 822 time zone
-0800
模式字母通常是重復(fù)的,其數(shù)量確定其精確表示:
Text: 對于格式化來說,如果模式字母的數(shù)量大于或等于 4,則使用完全形式;否則,在可用的情況下使用短形式或縮寫形式。對于分析來說,兩種形式都是可接受的,與模式字母的數(shù)量無關(guān)。
Number: 對于格式化來說,模式字母的數(shù)量是最小的數(shù)位,如果數(shù)位不夠,則用 0 填充以達到此數(shù)量。對于分析來說,模式字母的數(shù)量被忽略,除非必須分開兩個相鄰字段。
Year: 對于格式化來說,如果模式字母的數(shù)量為 2,則年份截取為 2 位數(shù),否則將年份解釋為 number。
對于分析來說,如果模式字母的數(shù)量大于 2,則年份照字面意義進行解釋,而不管數(shù)位是多少。因此使用模式 "MM/dd/yyyy",將 "01/11/12" 分析為公元 12 年 1 月 11 日。
在分析縮寫年份模式("y" 或 "yy")時,SimpleDateFormat 必須相對于某個世紀來解釋縮寫的年份。這通過將日期調(diào)整為 SimpleDateFormat 實例創(chuàng)建之前的 80 年和之后 20 年范圍內(nèi)來完成。例如,在 "MM/dd/yy" 模式下,如果 SimpleDateFormat 實例是在 1997 年 1 月 1 日創(chuàng)建的,則字符串 "01/11/12" 將被解釋為 2012 年 1 月 11 日,而字符串 "05/04/64" 將被解釋為 1964 年 5 月 4 日。在分析時,只有恰好由兩位數(shù)字組成的字符串(如 Character.isDigit(char) 所定義的)被分析為默認的世紀。其他任何數(shù)字字符串將照字面意義進行解釋,例如單數(shù)字字符串,3 個或更多數(shù)字組成的字符串,或者不都是數(shù)字的兩位數(shù)字字符串(例如"-1")。因此,在相同的模式下, "01/02/3" 或 "01/02/003" 解釋為公元 3 年 1 月 2 日。同樣,"01/02/-3" 分析為公元前 4 年 1 月 2 日。
Month: 如果模式字母的數(shù)量為 3 或大于 3,則將月份解釋為 text;否則解釋為 number。
General time zone: 如果時區(qū)有名稱,則將它們解釋為 text。對于表示 GMT 偏移值的時區(qū),使用以下語法:
GMTOffsetTimeZone:GMT Sign Hours : Minutes
Sign: one of + -
Hours:Digit Digit Digit
Minutes: Digit Digit
Digit: one of 0 1 2 3 4 5 6 7 8 9
Hours 必須在 0 到 23 之間,Minutes 必須在 00 到 59 之間。格式是與語言環(huán)境無關(guān)的,并且數(shù)字必須取自 Unicode 標準的 Basic Latin 塊。
對于分析來說,RFC 822 time zones 也是可接受的。
RFC 822 time zone: 對于格式化來說,使用 RFC 822 4-digit 時區(qū)格式:
RFC822TimeZone:
Sign TwoDigitHours Minutes
TwoDigitHours:
Digit Digit
TwoDigitHours 必須在 00 和 23 之間。其他定義請參閱 general time zones。
對于分析來說,general time zones 也是可接受的。
SimpleDateFormat 還支持本地化日期和時間模式 字符串。在這些字符串中,以上所述的模式字母可以用其他與語言環(huán)境有關(guān)的模式字母來替換。SimpleDateFormat 不處理除模式字母之外的文本本地化;而由類的客戶端來處理。
示例
以下示例顯示了如何在美國語言環(huán)境中解釋日期和時間模式。給定的日期和時間為美國太平洋時區(qū)的本地時間 2001-07-04 12:08:56。
日期和時間模式
結(jié)果
"yyyy.MM.dd G 'at' HH:mm:ss z"
2001.07.04 AD at 12:08:56 PDT
"EEE, MMM d, ''yy"
Wed, Jul 4, '01
"h:mm a"
12:08 PM
"hh 'o''clock' a, zzzz"
12 o'clock PM, Pacific Daylight Time
"K:mm a, z"
0:08 PM, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa"
02001.July.04 AD 12:08 PM
"EEE, d MMM yyyy HH:mm:ss Z"
Wed, 4 Jul 2001 12:08:56 -0700
"yyMMddHHmmssZ"
010704120856-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSZ"
2001-07-04T12:08:56.235-0700
同步
日期格式是不同步的。建議為每個線程創(chuàng)建獨立的格式實例。如果多個線程同時訪問一個格式,則它必須是外部同步的。