java時間操作三部曲之java.util.Date


    2016年8月來到一家新公司,認識了現在的CTO彪哥,也許和很多初出茅廬的程序員一樣,見到技術大神內心膜拜之情溢於言表。我也一樣,想跟着學這學那,不斷總結自己的不足,向彪哥請教。 寫博客的想法就是從彪哥那學的。

   第一次寫,也不知道寫些什么,我給自己的定位是:一·自己的學習筆記,方便以后溫習和工具查詢  二·也算是滿足自己的小虛榮吧,總覺得很多年以后在看現在寫的博客,會有一種滿足感。所以這一次,醞釀了很久打算寫一寫java中關於時間的操作,重新學習總結一下Date,Calendar,GregorienCalendar這三個類。

  今天這一篇就寫java.util.Date

  java.util.Date 類代表某一特定的時間,精確到毫秒。該類中所有方法接受或返回的年,月,日,時,分,秒和秒值都遵循以下規則

  YEAR(年)由一個整數表示y-1900(等會解釋為什么要-1900)

  MONTH(月)由一個整數表示從0-11,也就是說0表示0+1月,即0表示1月,1表示2月以此類推

  DAY(月日)由一個整數表示 1-31

  HOUR(小時)從0-23和年類似,0表示0+1點

  MINUTE(分)從0-59

   

類構造函數

1.Date() 這個構造函數分配一個Date對象並將它初始化,使它表示其被分配的時間,精確到毫秒。

java.util.Date date = new java.util.Date();

2.Date(String s) 接受一個時間字符串,設定某個時間,jdk1.1后不推薦使用了。

java.util.Date date = new java.util.Date("2016-10-26");

 3.Date(long date) 這個構造函數分配一個Date對象並初始化它代表指定的毫秒數,因為被稱為“紀元”,即1970年1月1日00:00:00 GMT標准基准時間。

 4.以上是幾個比較常用的構造函數,還有一些不常用的,並且在jdk1.1后不被推薦使用的,如:Date(int year, int month, int date),Date(int year, int month, int date, int hrs, int min)等。在使用上面兩個構造函數的時候 year 參數需要理想年-1900,例如2016年,作為參數用的話需要先減去1900年,也就是:

java.util.Date date = new java.util.Date (116,10,26);

//Date的源代碼如下
 @Deprecated
 public Date(int year, int month, int date, int hrs, int min, int sec) {
   int y = year + 1900;
    

 

類方法

1.boolean after(Date when)  此方法測試,此日期是否在指定日期之后。參數 when --進行檢查的日期;返回值:true表示代表Date對象是延遲與when表示的時刻,否則false

Date begin = new Date(116,10,26);
Date end = new Date(116,11,26);
System.out.println(begin.after(end));////輸出false 表示begin在end之前,end比begin晚

2.boolean before(Date when) 此方法測試,此日期是否在指定日期之前。和上面的方法相反

Date begin = new Date(116,10,26);
Date end = new Date(116,11,26);
System.out.println(begin.before(end));//輸出true 表示begin在end之前,早於end

 3.Object clone()  返回此Date對象的淺表副本。

 

Date begin = new Date(116,10,26);
Date clone=(Date) begin.clone();
System.out.println(begin);//Sat Nov 26 00:00:00 CST 2016
System.out.println(clone);//Sat Nov 26 00:00:00 CST 2016

2016-10-27補充:clone方法,在創建實體類的時候可能會用到,java核心技術卷1中有個警告:不要編寫返回引用可變對象的訪問器(getXX()方法)。什么意思呢,看下面代碼

public class Employee {
    
    private Date hireDay;//雇佣時間
    public Date getHireDay() {
        return hireDay;
    }
    public void setHireDay(Date hireDay) {
    this.hireDay = hireDay;
    }
    
    public static void main(String[] args) {
    //下面的代碼就會破壞封裝性
    Employee e=new Employee();
    e.setHireDay(new Date());
    System.out.println(e.getHireDay());//Thu Oct 27 10:09:05 CST 2016
    Date d=e.getHireDay();
    //因為e對象的hireDay和變量d引用同一個對象,一個修改了,另一個也會被修改
    d.setTime(12345768999999L);
    System.out.println(e.getHireDay());//Thu Mar 23 04:16:39 CST 2361
    }
}    

修改一下get,set方法

public Date getHireDay() {
    return (Date) hireDay.clone();
}
public void setHireDay(Date hireDay) {
    this.hireDay = (Date) hireDay.clone();
}

4.int compareTo(Date anotherDate)方法比較兩個日期。 參數:anotherDate要比較的日期;返回值:0如果參數日期等於此日期; 如果這個日期在Date參數之前返回一個小於0的值 ;  如果這個日期在Date參數之后返回一個大於0的值。

 Date date = new Date(98, 5, 21);
 Date date2 = new Date(99, 1, 9);

 // make 3 comparisons with them
 int comparison = date.compareTo(date2);
 int comparison2 = date2.compareTo(date);
 int comparison3 = date.compareTo(date);
 
 System.out.println("Comparison Result:" + comparison);//-1
 System.out.println("Comparison2 Result:" + comparison2);//1
 System.out.println("Comparison3 Result:" + comparison3);//0

5.long getTime() 方法返回自1970年1月1日00:00:00 GMT已經過去了多少毫秒,返回一個long類型的時間戳

Date begin = new Date(116,10,26);
System.out.println(begin.getTime());//1480089600000

 6.boolean equals(Object obj) 方法檢查如果兩個日期都是相等的,基於毫秒的差異。這個方法其實就是比較的兩個時間的long類型的時間戳是否相等,看源碼

public boolean equals(Object obj) {
    return obj instanceof Date && getTime() == ((Date) obj).getTime();
}

常用的方法也就這些,另外setTime(long time)是給他一個時間戳設置時間的。toString()方法是重寫了object的方法。

 

常見問題

1.比較時間的早晚

如果比較連個時間的早晚的話,建議使用原生態的Date的befor和after方法,效率相對要高,通過分析源碼,我們可以知道,其他就是比較的兩個long類型的數字

public boolean before(Date when) {
    return getMillisOf(this) < getMillisOf(when);
}

static final long getMillisOf(Date date) {
    if (date.cdate == null || date.cdate.isNormalized()) {
        return date.fastTime;
    }
    BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
    return gcal.getTime(d);
}

2.時間格式化

Date類型的時間格式話,需要借助java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss")對象,后面是要輸出的格式

/** 輸出格式: 2016-10-26 4:48:11*/
System.out.println((new java.text.SimpleDateFormat("yyyy-M-d h:mm:ss")).format(new Date()));
        
/** 輸出格式: 2016-10-26 16:48:11 */
System.out.println((new java.text.SimpleDateFormat("yyyy-M-d H:mm:ss")).format(new Date()));

這里需要注意的就是24時和12時的顯示正則,H大寫為24時計時法,h小寫為12時計時法,兩個h時,即hh,當為個位數時間時前面自動補0即下午4點顯示04

3.還有時間加減天數,建議借助工具類,后面會講到。但是這里呢還是要講一個問題,對於有些剛接觸java的朋友,在計算時間增減的時候喜歡用

System.out.println(new java.util.Date().getTime()-1000*60*60*24*30);  //計算一個月前的日期

這個時候得到的結果是不正確的,因為1000*60*60*24*30 這個計算后默認是int類型,但是實際的值已經超出了int類型存儲的長度,轉成long類型,萬事大吉。

4.還有一個是夏令時問題,原來Java中不是每天都是標准的24個小時,可能是23,也可能是25,日期的計算,使用Calendar提供的API,是不會出差錯的,簡單的new Date(long milliseconds)可能並不靠譜

 參考:http://www.cnblogs.com/snake-hand/archive/2013/06/10/3131157.html

5.java.util.Date 和 java.sql.Date的區別和相互轉化

util包下的Date是在除SQL語句外使用的,sql包下的Date是針對SQL語句中使用,它只有日期而沒有時間部分。

// java.sql.Date轉為java.util.Date
java.sql.Date date=new java.sql.Date();
java.util.Date d=new java.util.Date (date.getTime());

// java.util.Date轉為java.sql.Date
java.util.Date utilDate=new Date();
java.sql.Date sqlDate=new java.sql.Date(utilDate.getTime());

 

6.還有就是時區導致new Date()獲取的時間缺時少分,可以查看一下系統默認時間,當然后面提供的Calendar類都有了很好的改善

參考:http://blog.csdn.net/yohoph/article/details/7601377

 

第一次寫,先寫這么多吧,讓我對Date又有了一個新的認識。希望看到的朋友,對date有更高的認識或者對java中時間操作有更好的建議的,可以留言,多交流。2016-10-26

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM