1. 程式人生 > >JAVA日期時間小結

JAVA日期時間小結

Java 語言的CalendarGregorianCalendar (日曆),Date(日期), DateFormat(日期格式)組成了Java標準的一個基本但是非常重要的部分日期是商業邏輯計算一個關鍵的部分所有的開發者都應該能夠計算未來的日期定製日期的顯示格式並將文字資料解析成日期物件。學習日期日期格式日期的解析和日期的計算。我們將討論下面的類
1
具體類(和抽象類相對)java.util.Date 
2
抽象類java.text.DateFormat 和它的一個具體子類,java.text.SimpleDateFormat 
3
抽象類java.util.Calendar 
和它的一個具體子類,java.util.GregorianCalendar 
具體類可以被例項化但是抽象類卻不能你首先必須實現抽象類的一個具體子類.
1.   java.util.Date
及其格式化
Date 
類從Java 開發包(JDK) 1.0 就開始進化當時它只包含了幾個取得或者設定一個日期資料的各個部分的方法比如說月和年這些方法現在遭到了批評並且已經被轉移到了Calendar類裡去了我們將在本文中進一步討論它這種改進旨在更好的處理日期資料的國際化格式就象在JDK 1.1中一樣, Date 類實際上只是一個包裹類它包含的是一個長整型資料表示的是從
GMT(格林尼治標準時間)1970, 1  100:00:00這一刻之前或者是之後經歷的毫秒數
1.1. 
建立java.util.Date
Java
統計從197011日起的毫秒的數量表示日期。也就是說,例如,197012日,是在11日後的86400000毫秒。同樣的,19691231日是在197011日前86400000毫秒。JavaDate類使用long型別紀錄這些毫秒值.因為long是有符號整數,所以日期可以在197011日之前,也可以在這之後。Long型別表示的最大正值和最大負值可以輕鬆的表示290000000年的時間,這適合大多數人的時間要求。讓我們看一個使用系統的當前日期和時間建立一個日期物件並返回一個長整數的簡單例子
這個時間通常被稱為Java 虛擬機器(JVM)主機環境的系統時間
import java.util.Date; 
public class DateExample1 { 
public static void main(String[] args) { 
// Get the system date/time 
Date date = new Date(); 
// 
打印出具體的年,月,日,小時,分鐘,秒鐘以及時區
System.out.println(date.getTime()); 
}   

在星期六, 2001929下午大約是6:50的樣子上面的例子在系統輸出裝置上顯示的結果是 1001803809710. 在這個例子中,值得注意的是我們使用了Date 建構函式建立一個日期物件這個建構函式沒有接受任何引數而這個建構函式在內部使用了System.currentTimeMillis() 方法來從系統獲取日期
//1
年前日期
   java.util.Date myDate=new java.util.Date();  
   long myTime=(myDate.getTime()/1000)-60*60*24*365;
   myDate.setTime(myTime*1000);
   String mDate=formatter.format(myDate);
//
明天日期
   myDate=new java.util.Date(); 
   myTime=(myDate.getTime()/1000)+60*60*24;
   myDate.setTime(myTime*1000);
   mDate=formatter.format(myDate);
//
兩個時間之間的天數
   SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
   java.util.Date date= myFormatter.parse("2003-05-1"); 
   java.util.Date mydate= myFormatter.parse("1899-12-30");
   long  day=(date.getTime()-mydate.getTime())/(24*60*60*1000);
//
加半小時
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
java.util.Date date1 = format.parse("2002-02-28 23:16:00");
long Time=(date1.getTime()/1000)+60*30;
date1.setTime(Time*1000);
String mydate1=formatter.format(date1);
//
年月周求日期
SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM F E");
java.util.Date date2= formatter2.parse("2003-05 5 
星期五"); 
SimpleDateFormat formatter3 = new SimpleDateFormat("yyyy-MM-dd");
String mydate2=formatter3.format(date2);
//
求是星期幾
mydate= myFormatter.parse("2001-1-1");
SimpleDateFormat formatter4 = new SimpleDateFormat("E");
String mydate3=formatter4.format(mydate);
1.2. Date
格式化能以一種使用者明白的格式來顯示這個日期呢在這裡類java.text.SimpleDateFormat 和它的抽象基類 java.text.DateFormat。那麼現在我們已經知道了如何獲取從197011日開始經歷的毫秒數了我們如何才format 就派得上用場了
// 
我們能不能用下面的程式碼構件出 2001/8/8 8:8
    import java.io.*;
    import java.util.*;
    public class WhatIsDate
    {
        public static void main(String[] args) {
            Date date = new Date(2001, 8, 8, 8, 8, 8);
            System.out.println(date);
        }
    }
Java 
的編譯器竟然報如下資訊 (Sun JDK1.3, Windows 2000 中文下)
注意:
WhatIsDate.java 
使用或覆蓋一個不鼓勵使用的API注意:使用-deprecation重新編譯,以得到詳細資訊。!那麼 Date 物件究竟是為了滿足哪個需求呢?看來它不是用來實現基於年//日小時:分鐘的時間表述。我們檢視 Java 的文件,我們看到有 getTime() 方法,它返回的竟然是一個 long 值。文件進一步又告訴我們這個值代表了當前系統的時間離1970/1/1 0:0 的毫秒差,而且是在 GMT 時區下(也被稱為 EPOC)。如果我們指定的時間是在此之前的,那它將返回一個負數值。這個發現讓我們對 Date 物件有了一個全新的認識-Date 存放的是與 EPOC 的偏差值。換而言之我們也可通過 long 型別來表示時間?對了,這個猜想是得到了 Java 的支援:
   // 
第二種獲得當前時間的方法
    long dateInMilliSeconds = System.currentTimeMillis();
    // 
這時候打印出的只是一串數字而已
    System.out.println(dateInMilliSeconds);
對程式執行效率敏感的程式設計師可以發現這個方法只是生成一個 Java 的原始型別 (primitive type) long, 不需要例項化一個物件。因此如果我們對時間的處理只是在內部進行時,可以用 long 來代替 Date 物件。最典型的應用就是在一段程式碼開始和結束時,分別獲得系統當前的時間,然後計算出程式碼執行所需的時間(微秒級)
   long start = System.currentTimeMillis();
    // 
程式碼段
    System.out.println("
需要 "+(System.currentTimeMillis()-start)+" 微秒");
那麼當我們要把這個 long 值已更為友好的表現形式顯示處理的時候,我們可以用它來構造 Date 物件:
Date date = new Date(dateInMilliSeconds);
System.out.println(date);
我們看到了在 Java 中對時間最為基本的表示,有通過對EPOC 的偏差值進行處理。Date 物件是對它的一個物件的封裝。我們同時也看到了,在現時世界中我們對時間的描述通常是通過"某年某月某日某時某分"來定義的。Date 的顯示(實際上是 toString() 方法)描述了這些資訊,但 Java 並不建議我們用這種方式直接來構件 Date 物件。因此我們需要找出哪個物件可以實現這個需求。這就是我們下面就要講述的 Calendar 物件的功能。在我們進一步研究 Calendar 之前,請記住 Date 只是一個對 long (基於 GMT 時區)的物件封裝。它所表現出來的年//日小時:分鐘時區的時間表述,只是它的 toString() 方法所提供的。千萬不要為這個假象所迷惑。假如我們希望定製日期資料的格式比方星期六-9-29-2001下面的例子展示瞭如何完成這個工作
import java.text.SimpleDateFormat; 
import java.util.Date; 
public class DateExample2 { 
public static void main(String[] args) { 
SimpleDateFormat bartDateFormat = new SimpleDateFormat("EEEE-MMMM-dd-yyyy"); Date date = new Date(); 
System.out.println(bartDateFormat.format(date)); 
}
}
只要通過向SimpleDateFormat 的建構函式傳遞格式字串"EEE-MMMM-dd-yyyy", 我們就能夠指明自己想要的格式你應該可以看見格式字串中的ASCII 字元告訴格式化函式下面顯示日期資料的哪一個部分. EEEE是星期, MMMM是月, dd是日, yyyy是年字元的個數決定了日期是如何格式化的.傳遞"EE-MM-dd-yy"會顯示 Sat-09-29-01. 請察看Sun 公司的Web 站點獲取日期格式化選項的完整的指示
1.3. 
文字資料解析成日期物件假設我們有一個文字字串包含了一個格式化了的日期物件而我們希望解析這個字串並從文字日期資料建立一個日期物件我們將再次以格式化字串"MM-dd-yyyy" 呼叫SimpleDateFormat但是這一次我們使用格式化解析而不是生成一個文字日期資料我們的例子顯示在下面將解析文字字串"9-29-2001"並建立一個值為001736000000 的日期物件
通過parse()方法,DateFormat能夠以一個字串創立一個Date物件。這個方法能丟擲ParseException異常,所以你必須使用適當的異常處理技術。例子程式
import java.text.SimpleDateFormat; 
import java.util.Date; 
public class DateExample3 { 
public static void main(String[] args) { 
// Create a date formatter that can parse dates of 
// the form MM-dd-yyyy. 
SimpleDateFormat bartDateFormat = new SimpleDateFormat("MM-dd-yyyy"); 
// Create a string containing a text date to be parsed. 
String dateStringToParse = "
9-29-2001"; 
try { 
// Parse the text version of the date. 
// We have to perform the parse method in a 
// try-catch construct in case dateStringToParse 
// does not contain a date in the format we are expecting. 
Date date = bartDateFormat.parse(dateStringToParse); 
// Now send the parsed date as a long value 
// to the system output. 
System.out.println(date.getTime()); 
}catch (Exception ex) { 
System.out.println(ex.getMessage()); 
}


1.4. 
使用標準的日期格式化過程既然我們已經可以生成和解析定製的日期格式了讓我們來看一看如何使用內建的格式化過程方法 DateFormat.getDateTimeInstance() 讓我們得以用幾種不同的方法獲得標準的日期格式化過程在下面的例子中我們獲取了四個內建的日期格式化過程它們包括一個短的中等的長的和完整的日期格式
import java.text.DateFormat; 
import java.util.Date; 
public class DateExample4 { 
public static void main(String[] args) { 
Date date = new Date(); 
DateFormat shortDateFormat = DateFormat.getDateTimeInstance( 
DateFormat.SHORT, DateFormat.SHORT); 
DateFormat mediumDateFormat = DateFormat.getDateTimeInstance( 
DateFormat.MEDIUM, DateFormat.MEDIUM); 
DateFormat longDateFormat = DateFormat.getDateTimeInstance( 
DateFormat.LONG, DateFormat.LONG); 
DateFormat fullDateFormat = DateFormat.getDateTimeInstance( 
DateFormat.FULL, DateFormat.FULL); 
System.out.println(shortDateFormat.format(date)); System.out.println(mediumDateFormat.format(date)); System.out.println(longDateFormat.format(date)); System.out.println(fullDateFormat.format(date)); 


注意我們在對 getDateTimeInstance的每次呼叫中都傳遞了兩個值第一個引數是日期風格而第二個引數是時間風格它們都是基本資料型別int(整型). 考慮到可讀性我們使用了DateFormat 類提供的常量: SHORT, MEDIUM, LONG,  FULL. 要知道獲取時間和日期格式化過程的更多的方法和選項請看Sun 公司Web 站點上的解釋
執行我們的例子程式的時候它將向標準輸出裝置輸出下面的內容
9/29/01 8:44 PM 
Sep 29, 2001 8:44:45 PM 
September 29, 2001 8:44:45 PM EDT 
Saturday, September 29, 2001 8:44:45 PM EDT 
2.   Calendar 
日曆類首先請記住 Calendar 只是一個抽象類也就是說你無法直接獲得它的一個例項,換而言之你可以提供一個自己開發的 Calendar 物件。那究竟什麼是一個 Calendar 呢?中文的翻譯就是日曆,那我們立刻可以想到我們生活中有陽()歷、陰()歷之分。它們的區別在哪呢?比如有:月份的定義 - `()一年12 個月,每個月的天數各不同;陰()歷,每個月固定28,每週的第一天 - ()歷星期日是第一天;陰()歷,星期一是第一天實際上,在歷史上有著許多種紀元的方法。它們的差異實在太大了,比如說一個人的生日是"八月八日那麼一種可能是陽()歷的八月八日,但也可以是陰()歷的日期。所以為了計時的統一,必需指定一個日曆的選擇。那現在最為普及和通用的日曆就是 "Gregorian Calendar"。也就是我們在講述年份時常用 "公元几几年"Calendar 抽象類定義了足夠的方法,讓我們能夠表述日曆的規則。Java 本身提供了對 "Gregorian Calendar" 規則的實現。我們從 Calendar.getInstance() 中所獲得的例項就是一個 "GreogrianCalendar" 物件(與您通過 new GregorianCalendar() 獲得的結果一致)下面的程式碼可以證明這一點:
   import java.io.*;
    import java.util.*;
    public class WhatIsCalendar
    {
        public static void main(String[] args) {
            Calendar calendar = Calendar.getInstance();
            if (calendar instanceof GregorianCalendar)
                System.out.println("It is an instance of GregorianCalendar");
        }
    }
Calendar 
 Java 中是一個抽象類(Abstract Class)GregorianCalendar 是它的一個具體實現。
Calendar 
 Date 的轉換非常簡單:
   Calendar calendar = Calendar.getInstance();
    // 
從一個 Calendar 物件中獲取 Date 物件
    Date date = calendar.getTime();
    // 
 Date 物件反應到一個 Calendar 物件中,
    // Calendar/GregorianCalendar 
沒有建構函式可以接受 Date 物件
    // 
所以我們必需先獲得一個例項,然後設定 Date 物件
    calendar.setTime(date);
Calendar 
物件在使用時,有一些值得注意的事項:
1. Calendar 
 set() 方法
set(int field, int value) - 
是用來設定"///小時/分鐘//微秒"等值
field 
的定義在 Calendar 
set(int year, int month, int day, int hour, int minute, int second) 
但沒有set(int year, int month, int day, int hour, int minute, int second, int millisecond) 前面 set(int,int,int,int,int,int) 方法不會自動將 MilliSecond 清為 0另外,月份的起始值為0而不是1,所以要設定八月時,我們用7而不是8
calendar.set(Calendar.MONTH, 7);
我們通常需要在程式邏輯中將它清為 0,否則可能會出現下面的情況:
   import java.io.*;
    import java.util.*;
    public class WhatIsCalendarWrite
    {
        public static void main(String[] args) throws Exception{
            ObjectOutputStream out =
                new ObjectOutputStream(
                    new FileOutputStream("calendar.out"));
            Calendar cal1 = Calendar.getInstance();