Java基礎(chǔ)進(jìn)階 工具類和時(shí)間日期類

1、工具類

Java中提供了大量的類和接口完成特定的功能。每個(gè)類都會(huì)有自己的屬性和行為(功能)。但是這些功能還是不能滿足所有的需求。于是Java中又對(duì)某些類提供的額外的功能。而把這些功能定義在特定的類中。
比如:集合類,每個(gè)集合類都提供可以操作自己這個(gè)集合容器中元素的函數(shù)。比如:添加元素、刪除元素、修改元素、獲取元素。而在開(kāi)發(fā)中,對(duì)集合操作時(shí),這些函數(shù)依然不夠用。例:對(duì)有角標(biāo)的集合進(jìn)行排序、獲取集合中最大值或者最小值等功能。于是Java又對(duì)這些集合類提供更多的功能,把這些功能定義在一個(gè)Collections類中。這個(gè)Collections類是一個(gè)專門給集合增加額外補(bǔ)充功能的類。

把這些專門提供補(bǔ)充或者額外增加功能的類在Java中稱為工具類。
工具類的特點(diǎn):
Java中所有的工具類中的函數(shù)全部都是靜態(tài)的。并且工具類一般都會(huì)保存在java.util包下。

補(bǔ)充:如果自己在開(kāi)發(fā)項(xiàng)目的時(shí)候,在整個(gè)項(xiàng)目中會(huì)專門建一個(gè)包來(lái)存放工具類的。
這個(gè)包我們一般這樣命名:cn.xuexi.utils。

1.1、Collections工具類介紹

1.png

Collections工具類,主要就是操作集合的。如果當(dāng)操作集合的時(shí)候,發(fā)現(xiàn)集合的方法不夠用了,這時(shí)一定要先到Collections工具類中找有沒(méi)有適合我們需求的功能。

Collections類中的常用方法:

1)

2.png

把可變參數(shù)指定的對(duì)象存放到指定的c集合中。

   public static <T> boolean addAll(Collection<?> c,T... elements)
3.png

2)對(duì)指定的集合進(jìn)行排序。

 public static <T> void sort(List<T> list)
4.png

3)二分法查找或者叫做折半查找。

說(shuō)明:使用二分法查找前提是一定要排序。否則查找的結(jié)果不是我們想要的。

 public static <T> <u>int</u> binarySearch(List<?> list,T key)

需求:找一下12在集合中的位置。

5.png

注意:根據(jù)指定的集合中的元素找對(duì)應(yīng)的下標(biāo),如果指定的元素不在集合中。則返回(-(插入點(diǎn)) - 1),不是返回-1。按排序后插入數(shù)據(jù)。

6.png

4)求集合中元素的最大值。

  public static <T> T max(Collection<?> <u>coll</u>)
7.png

5)把指定的list集合中的元素進(jìn)行反轉(zhuǎn)。

public static void reverse(List<?> list)
8.png

6) 打亂集合中的數(shù)據(jù)順序,這個(gè)函數(shù)經(jīng)常使用在寫撲克牌游戲中。

 public static void shuffle(List<?> list)
9.png

代碼演示如下所示:

分析和步驟:
1)創(chuàng)建ArrayList<Integer>集合list,泛型是Integer;
2)使用集合對(duì)象list調(diào)用add函數(shù)向集合中添加幾個(gè)整數(shù)類型的數(shù)據(jù);
3)分別演示上述函數(shù)的功能;

package cn.xuexi.collections.demo;
import java.util.ArrayList;
import java.util.Collections;
/*
 * Collections的其他函數(shù)演示
 * public static <T> void sort(List<T> list) 對(duì)指定的集合進(jìn)行排序
 * public static <T> int binarySearch(List<?> list,T key) 根據(jù)指定的集合中的元素查找對(duì)應(yīng)的下標(biāo)
 * public static <T> T max(Collection<?> coll) 求集合中元素的最大值
 * public static void reverse(List<?> list) 把指定的集合中的元素進(jìn)行反轉(zhuǎn)
 * public static void shuffle(List<?> list) 打亂集合中數(shù)據(jù) 
 */
public class CollectionsDemo1 {
    public static void main(String[] args) {
        // 創(chuàng)建集合對(duì)象
        ArrayList<Integer> list = new ArrayList<Integer>();
        //向集合中添加數(shù)據(jù)
        Collections.addAll(list, 12,34,2,18,57);
        //輸出原始的集合
        System.out.println(list);
        //對(duì)集合進(jìn)行排序
        Collections.sort(list);
        //輸出排序后的集合
        System.out.println("排序后"+list);
        //需求:找一下12在集合中的位置 list表示集合名,12表示集合中的數(shù)據(jù)
        int index = Collections.binarySearch(list,12); 
        System.out.println(index);
        //求集合中元素的最大值
        Integer max = Collections.max(list);
        System.out.println("max="+max);
        //把指定集合中的元素進(jìn)行反轉(zhuǎn)
        Collections.reverse(list);
        System.out.println("反轉(zhuǎn)后的集合"+list);
        //打亂集合中的數(shù)據(jù)
        Collections.shuffle(list);
        //輸出打亂后的集合數(shù)據(jù)
        System.out.println("打亂后的集合"+list);
    }
}

1.2、Arrays工具類介紹

Arrays它是數(shù)組的工具類:

10.png

Arrays工具類中提供數(shù)組的:二分查找,復(fù)制數(shù)組,填充數(shù)組,排序,把數(shù)組轉(zhuǎn)成字符串。但是沒(méi)有提供對(duì)數(shù)組中的數(shù)據(jù)進(jìn)行反轉(zhuǎn),求數(shù)組中的最值問(wèn)題。
如果我們能夠把數(shù)組轉(zhuǎn)成集合,就可以使用Collections工具類中的最值和反轉(zhuǎn)功能。
也就是說(shuō)數(shù)組轉(zhuǎn)換為集合的目的就是為了使用集合中的方法操作數(shù)組中的元素。

數(shù)組轉(zhuǎn)集合的函數(shù):

11.png
 public static <T> List<T> asList(T... a)

數(shù)組轉(zhuǎn)成集合使用Arrays中的asList方法。
注意:將數(shù)組轉(zhuǎn)成集合需要注意以下幾點(diǎn):
1)將數(shù)組轉(zhuǎn)為一個(gè)集合,得到的集合長(zhǎng)度固定。集合長(zhǎng)度不能改變。
也就是說(shuō)數(shù)組轉(zhuǎn)換后的集合不能對(duì)集合增刪元素,元素可以修改。
2)使用asList函數(shù)將數(shù)組轉(zhuǎn)換為集合,由于asList函數(shù)的參數(shù)是可變參數(shù),可以接收數(shù)組;
3)如果數(shù)組中存儲(chǔ)的是引用數(shù)據(jù)類型的數(shù)據(jù),比如字符串String類等,那么返回值List<T>的泛型是是String,而不是String[] 。

因?yàn)閿?shù)組中保存的是引用數(shù)據(jù)類型的字符串對(duì)象,而集合是用來(lái)保存對(duì)象的,所以數(shù)組中的每個(gè)字符串對(duì)象數(shù)據(jù)都會(huì)放在集合中作為集合元素。

分析和步驟:
a.定義一個(gè)測(cè)試類ArraysDemo;
b.在這個(gè)類中的主函數(shù)中定義一個(gè)字符串?dāng)?shù)組,存儲(chǔ)幾個(gè)字符串,使用Arrays類調(diào)用asList()函數(shù)將數(shù)組轉(zhuǎn)換為集合;
c.由于asList()函數(shù)是可變參數(shù)也可以接收可變參數(shù),所以傳遞幾個(gè)字符串作為可變參數(shù)在生成一個(gè)新的集合;
d.分別使用上述生成集合的對(duì)象演示對(duì)集合增刪改操作,并輸出結(jié)果;

package cn.xuexi.arrays.demo;
import java.util.Arrays;
import java.util.List;
/*
 * public static <T> List<T> asList(T... a) 
 * 使用上述函數(shù)將數(shù)組轉(zhuǎn)換為集合,然后可以使用集合中的函數(shù)來(lái)操作數(shù)組
 * 注意:由于數(shù)組長(zhǎng)度是固定的,轉(zhuǎn)化為集合后,集合的長(zhǎng)度也不能被改變
 */
public class ArraysDemo {
    public static void main(String[] args) {
        //創(chuàng)建數(shù)組
       //String[] arr={"hello","java","world"};
        /*
         * 使用asList函數(shù)將數(shù)組轉(zhuǎn)換為集合
         * 由于asList函數(shù)的參數(shù)是可變參數(shù),可以接收數(shù)組
         * 注意這里的泛型是String,不是String[] 
         * 因?yàn)閿?shù)組中保存的是引用數(shù)據(jù)類型的字符串對(duì)象,而集合是用來(lái)保存對(duì)象的
         * 所以數(shù)組中的每個(gè)字符串對(duì)象數(shù)據(jù)都會(huì)放在集合中作為集合元素
         */
        //List<String> list = Arrays.asList(arr);
        //由于asList(T... a) 函數(shù)的參數(shù)是可變參數(shù),所以可以向如下方式傳遞數(shù)據(jù),
        //其實(shí)可變參數(shù)就是個(gè)數(shù)組  而參數(shù)的類型 T和集合的泛型一樣都是String類型
        //T... a ={"hello","java","world"} T[] a={"hello","java","world"};
        //String[] a={"hello","java","world"};
        List<String> list = Arrays.asList("hello","java","world");
        //輸出list [hello, java, world]
        //System.out.println(list);
        //向生成的集合中添加數(shù)據(jù)
        //list.add("哈哈");//不能向該集合中添加元素 否則報(bào)異常  java.lang.UnsupportedOperationException
        //list.remove(1);//不能刪除該集合中的元素 否則報(bào)異常  java.lang.UnsupportedOperationException
        //可以修改集合中的數(shù)據(jù),但是不能改變集合的長(zhǎng)度
        list.set(0, "哈哈");
        System.out.println(list);
    }
}

4)如果數(shù)組中存儲(chǔ)的是基本數(shù)據(jù)類型,那么數(shù)組轉(zhuǎn)成集合,會(huì)把整個(gè)數(shù)組作為一個(gè)對(duì)象存儲(chǔ)到集合中;

代碼如下所示:

分析和步驟:
a.在上述類中的主函數(shù)中定義一個(gè)int[]數(shù)組,存儲(chǔ)幾個(gè)int類型的數(shù)據(jù);
b.使用Arrays類調(diào)用asList()函數(shù)將數(shù)組轉(zhuǎn)換為集合,并輸出結(jié)果;


12.png

說(shuō)明:輸出集合名字能夠輸出一串地址,說(shuō)明list集合中存儲(chǔ)的是一個(gè)一維數(shù)組的一串地址,也就是說(shuō)將數(shù)組整體作為集合的一個(gè)對(duì)象元素存儲(chǔ)到集合中。

上述代碼內(nèi)存圖解如下所示:

13.png

總結(jié):如果想將數(shù)組轉(zhuǎn)換為集合,讓集合操作數(shù)組中的元素建議不要將基本數(shù)據(jù)類型數(shù)組轉(zhuǎn)換為集合,可以將基本類型的數(shù)組變成對(duì)應(yīng)的包裝類類型數(shù)組在轉(zhuǎn)換為集合即可。

5)如果數(shù)組中存儲(chǔ)的是引用類型的元素,在把數(shù)組轉(zhuǎn)為集合后,該集合中存儲(chǔ)的就是數(shù)組中的所有引用類型的元素;

代碼實(shí)現(xiàn)如下所示:
分析和步驟:
1)在上述類中的主函數(shù)中定義一個(gè)String[]數(shù)組,存儲(chǔ)幾個(gè)String類型的數(shù)據(jù);
2)使用Arrays類調(diào)用asList()函數(shù)將String類型的數(shù)組轉(zhuǎn)換為集合,并輸出結(jié)果;
3)在上述類中的主函數(shù)中定義一個(gè)Integer[]數(shù)組,存儲(chǔ)幾個(gè)Integer類型的數(shù)據(jù);
4)使用Arrays類調(diào)用asList()函數(shù)將Integer類型的數(shù)組轉(zhuǎn)換為集合,并輸出結(jié)果;

14.png

說(shuō)明:Integer[]數(shù)組保存的是基本數(shù)據(jù)類型的包裝類的對(duì)象的地址,屬于引用數(shù)據(jù)類型,所以會(huì)將每一個(gè)數(shù)據(jù)保存到集合中。

上述代碼的內(nèi)存圖解如下所示:

15.png

總結(jié):
1)在開(kāi)發(fā)中不建議將基本類型的數(shù)組通過(guò)asList()函數(shù)轉(zhuǎn)換為集合,因?yàn)檗D(zhuǎn)換結(jié)果是地址,不是數(shù)組中的數(shù)據(jù),可以將基本類型的數(shù)組換成對(duì)應(yīng)的包裝類類型數(shù)組進(jìn)行轉(zhuǎn)換;
2)把數(shù)組轉(zhuǎn)成集合就是為了使用集合中的功能操作數(shù)組;

2、Date類介紹

在生活中有日期這樣的數(shù)據(jù),Java對(duì)日期這類數(shù)據(jù)也進(jìn)行了類的描述和封裝。

16.png

說(shuō)明:
1)類 Date 表示特定的瞬間,精確到毫秒。
2)Date類,在JDK1.0的時(shí)候提供了大量的函數(shù),可以進(jìn)行年月日時(shí)分秒的轉(zhuǎn)換,以及字符串和日期之間的轉(zhuǎn)換和解析。后期從JDK1.1開(kāi)始 ,年月日時(shí)分秒的轉(zhuǎn)換交給了Calendar 類 ,而字符串和日期之間的轉(zhuǎn)換交給了DateFormat類。

Date類中沒(méi)有過(guò)時(shí)的構(gòu)造函數(shù)如下:

17.png

創(chuàng)建一個(gè)Date對(duì)象,封裝就是當(dāng)前系統(tǒng)的時(shí)間信息。

18.png

把一個(gè)毫秒值封裝成Date對(duì)象。

代碼演示如下所示:
分析和步驟:
1)創(chuàng)建一個(gè)測(cè)試類DateDemo;
2)在這個(gè)類中的main函數(shù)中使用new關(guān)鍵字創(chuàng)建Date類的對(duì)象d;
3)輸出當(dāng)前的系統(tǒng)時(shí)間d;
4)根據(jù)日期對(duì)象d調(diào)用getTime()函數(shù)獲得日期對(duì)象的毫秒值time,輸出time值;
5)使用System調(diào)用currentTimeMillis()函數(shù)獲得當(dāng)前系統(tǒng)的毫秒值time2,輸出毫秒值time2;
6)把毫秒值time2作為Date類的構(gòu)造函數(shù)的參數(shù)生成日期類對(duì)象d2,并輸出d2;

package cn.xuexi.date.demo;
import java.util.Date;
/*
 * Date類的演示
 */
public class DateDemo {
    public static void main(String[] args) {
        /*
         * 創(chuàng)建一個(gè)日期對(duì)象
         * 使用空參構(gòu)造函數(shù)把當(dāng)前的系統(tǒng)時(shí)間封裝成Date類的對(duì)象
         */
        Date d = new Date();
        //輸出當(dāng)前系統(tǒng)時(shí)間d
        System.out.println(d);
        //根據(jù)日期對(duì)象d獲得毫秒值
        long time = d.getTime();
        System.out.println(time);
        //使用System類中的函數(shù)獲得當(dāng)前系統(tǒng)的毫秒值
        long time2 = System.currentTimeMillis();
        System.out.println(time2);
        //根據(jù)毫秒值創(chuàng)建日期類的對(duì)象
        Date d2 = new Date(time2);
        System.out.println(d2);
    }
}

Date類沒(méi)有過(guò)時(shí)的其他函數(shù):


19.png

已經(jīng)有一個(gè)Date對(duì)象,但是我們可以修改這個(gè)Date對(duì)象表示的毫秒值數(shù)據(jù)。

20.png

在Date類中必須知道怎么把毫秒值轉(zhuǎn)成Date對(duì)象,以及怎么把Date對(duì)象轉(zhuǎn)成毫秒值。

1.毫秒值轉(zhuǎn)成Date對(duì)象:構(gòu)造函數(shù) Date(long time) 使用函數(shù) setTime(long time);
2.Date對(duì)象轉(zhuǎn)成毫秒值:使用函數(shù)getTime() System.currentTimeMillis()

3、DateFormat類介紹

21.png

說(shuō)明:
1)在Java中看到文本,統(tǒng)一把這樣的數(shù)據(jù)當(dāng)做String處理;
2)DateFormat是一個(gè)抽象類,不能實(shí)例化。需要使用該類中的一個(gè)靜態(tài)方法獲取對(duì)象:

22.png

補(bǔ)充: 對(duì)于getDateInstance()函數(shù)而言,這里的日期默認(rèn)風(fēng)格是:年-月-日。yyyy-MM-dd

舉例:2015-12-27

23.png

補(bǔ)充: 對(duì)于getDateTimeInstance()函數(shù)而言,這里的日期默認(rèn)風(fēng)格是:年-月-日 時(shí):分:秒。 yyyy-MM-dd HH:mm:ss。

舉例:2015-12-27 15:42:30

3)DateFormat類:可以把日期對(duì)象轉(zhuǎn)成字符串?dāng)?shù)據(jù)(格式化),或者把字符串?dāng)?shù)據(jù)轉(zhuǎn)成日期對(duì)象(解析);
A:日期轉(zhuǎn)為字符串(格式化日期對(duì)象)

24.png

B:字符串轉(zhuǎn)為日期(解析日期格式的字符串)

25.png

案例1:DateFormat簡(jiǎn)單使用
需求:把當(dāng)前系統(tǒng)時(shí)間使用format(Date date)函數(shù)轉(zhuǎn)換為字符串(格式化功能)。
分析和步驟:
1)使用DateFormat類調(diào)用getDateInstance()函數(shù)獲得日期格式化解析的對(duì)象df;
2)創(chuàng)建當(dāng)前系統(tǒng)的日期的對(duì)象d,new Date();
3)使用日期格式化解析的對(duì)象df調(diào)用format函數(shù),把當(dāng)前系統(tǒng)日期對(duì)象d轉(zhuǎn)為字符串格式并輸出;

package cn.xuexi.date.demo;
import java.text.DateFormat;
import java.util.Date;
/*
 * 需求:把當(dāng)前系統(tǒng)時(shí)間使用format函數(shù)轉(zhuǎn)換為字符串(格式化功能)。
 */
public class DateFormatDemo {
    public static void main(String[] args) {
        /*
         * 創(chuàng)建DateFormat類的對(duì)象
         * 由于DateFormat類是抽象類不能使用new關(guān)鍵字創(chuàng)建對(duì)象
         * 所以只能使用DateFormat類名調(diào)用函數(shù)來(lái)獲得對(duì)象
         */
        //DateFormat df = DateFormat.getDateInstance();
        //System.out.println(df);//輸出內(nèi)容java.text.SimpleDateFormat@ef7951d7
        DateFormat df2 = DateFormat.getDateTimeInstance();
        //獲得當(dāng)前系統(tǒng)的時(shí)間
        Date d = new Date();
       //System.out.println(d);//輸出結(jié)果Tue Dec 27 00:27:02 GMT+08:00 2015
        //使用DateFormat類的對(duì)象df調(diào)用format函數(shù)把當(dāng)前系統(tǒng)時(shí)間轉(zhuǎn)換為字符串
        /*String newDate = df.format(d);
        System.out.println(newDate);//輸出內(nèi)容:2015-12-27
        */  
        String newDate2 = df2.format(d);
        System.out.println(newDate2);//輸出內(nèi)容是2015-12-27 15:42:30
      }
}

案例2:把字符串對(duì)象轉(zhuǎn)為日期對(duì)象(解析功能)

  • 需求:把當(dāng)前系統(tǒng)時(shí)間使用format函數(shù)轉(zhuǎn)換為字符串(格式化功能)。
    需求:將一個(gè)字符串對(duì)象"2016年10月19 日15時(shí)42分30秒”解析為日期格式的對(duì)象。
    說(shuō)明:getDateTimeInstance()的日期格式是:yyyy-MM-dd HH:mm:ss。

分析和步驟:
1)使用DateFormat類調(diào)用getDateTimeInstance()函數(shù)獲得日期格式化解析的對(duì)象df;
2)定義一個(gè)String類型的字符串strDate="2016年10月19 日15時(shí)42分30秒";
3)使用日期格式化解析的對(duì)象df調(diào)用parse()函數(shù)對(duì)上述字符串strDate進(jìn)行解析;
4)輸出解析后的數(shù)據(jù);

26.png

結(jié)論:在進(jìn)行解析時(shí),必須保證字符串的日期格式和要解析的對(duì)象屬于同一種格式
改進(jìn)程序:

27.png

4、SimpleDateFormat類介紹(掌握)

28.png

說(shuō)明:DateFormat類和子類SimpleDateFormat它們的主要功能就是完成日期和字符串之間的轉(zhuǎn)換。

SimpleDateFormat類有一個(gè)比較重要的構(gòu)造函數(shù)如下所示:

29.png

開(kāi)發(fā)中經(jīng)常使用上述構(gòu)造函數(shù)創(chuàng)建SimpleDateFormat對(duì)象。因?yàn)樯鲜鰳?gòu)造函數(shù)在創(chuàng)建對(duì)象的時(shí)候,可以指定樣式來(lái)對(duì)日期進(jìn)行解析或格式化。

日期和時(shí)間的常見(jiàn)模式如下所示:

30.png

說(shuō)明:
在使用SimpleDateFormat對(duì)日期數(shù)據(jù)進(jìn)行格式化或者解析的時(shí)候,指定的模式:
yy表示簡(jiǎn)寫的年份: 18年
yyyy表示全年: 2018年
M表示簡(jiǎn)寫的月份: 6月
MM表示全月:06月
d 表示日:1
dd 表示日:01號(hào)
H小時(shí): 8時(shí)
HH小時(shí):08時(shí)
m分鐘: 8分
mm分鐘:08分
s秒:9秒
ss 秒:09秒

案例:使用SimpleDateFormat對(duì)象自定義風(fēng)格解析和格式化日期對(duì)象。

需求:給定日期格式:yyyy年MM月dd日 HH時(shí)mm分ss秒。將當(dāng)前系統(tǒng)時(shí)間按照給定的日期格式進(jìn)行格式化,并輸出結(jié)果。

代碼如下所示:
分析和步驟:
1)定義一個(gè)測(cè)試類SimpleDateFormatDemo 類;
2)在這個(gè)類中的main函數(shù)中創(chuàng)建一個(gè)自定義的格式化解析器對(duì)象 要求參數(shù)格式:yyyy年MM月dd日 HH時(shí)mm分ss秒;
3)創(chuàng)建系統(tǒng)時(shí)間對(duì)象date,輸出date;
4)將日期格式化為字符串newDate,并輸出;

public class SimpleDateFormatDemo {
    public static void main(String[] args) {
        // 創(chuàng)建一個(gè)自定義的格式化解析器對(duì)象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH時(shí)mm分ss秒");
        //創(chuàng)建系統(tǒng)日期對(duì)象
        Date date = new Date();
        //輸出日期
        System.out.println(date);
        //將日期格式化為字符串
        String newDate = sdf.format(date);
        //輸出格式化后的日期
        System.out.println(newDate);
      }
}

需求:將字符串"2018/06/01 13時(shí)17:20秒"按照指定日期格式"yyyy/MM/dd HH時(shí)mm:ss秒"解析成為系統(tǒng)日期時(shí)間。
分析和步驟:
1)定義一個(gè)測(cè)試類SimpleDateFormatDemo1 類;
2)在這個(gè)類中的main函數(shù)中創(chuàng)建一個(gè)自定義的格式化解析器對(duì)象sdf, 要求參數(shù)格式:yyyy/MM/dd HH時(shí)mm:ss秒;
3)定義一個(gè)字符串s用來(lái)保存日期:"2018/06/01 13時(shí)17:20秒";
4)使用日期格式化對(duì)象sdf調(diào)用parse()函數(shù)將字符串s解析成系統(tǒng)日期時(shí)間date,并輸出轉(zhuǎn)換后的日期date;

package cn.xuexi.date.demo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
 * 案例:使用SimpleDateFormat對(duì)象自定義風(fēng)格解析和格式化日期對(duì)象
 */
public class SimpleDateFormatDemo {
    public static void main(String[] args) {
        //將字符串解析成為系統(tǒng)日期時(shí)間
        //定義一個(gè)字符串
        String strDate="2018/06/01 13時(shí)17:20秒";
        // 創(chuàng)建一個(gè)自定義的格式化解析器對(duì)象
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH時(shí)mm:ss秒");
        //使用sdf2調(diào)用parse()函數(shù)將上述字符串strDate解析成系統(tǒng)日期時(shí)間
        try {
            Date date2 = sdf2.parse(strDate);
            System.out.println(date2);
        } catch (Exception e) {
            System.out.println("日期格式不對(duì),應(yīng)該是:yyyy/MM/dd HH時(shí)mm:ss秒");
        }
    }
}

練習(xí):"2014-08-09 09:09:09" 與 "2026年08/01 10:10:10" 相差多少個(gè)月。

分析和思路:
2個(gè)字符串形式表示的日期數(shù)據(jù),要計(jì)算時(shí)間差,首先就需要獲取到當(dāng)前字符串表示的Date對(duì)象,然后通過(guò)Date對(duì)象在獲取日期對(duì)象的毫秒值。
毫秒值是long型的數(shù)據(jù),就可以使用算術(shù)運(yùn)算計(jì)算差值。

分析和步驟:
1)創(chuàng)建一個(gè)SimpleDateFormatTest 測(cè)試類;
2)在這個(gè)類中的main函數(shù)中創(chuàng)建一個(gè)自定義的格式化解析器對(duì)象
sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3)在創(chuàng)建一個(gè)自定義的格式化解析器對(duì)象
sdf2=new SimpleDateFormat("yyyy年MM/dd HH:mm:ss");
4)定義兩個(gè)字符串s1和s2分別保存"2014-08-09 09:09:09"和"2026年08/01 10:10:10";
5)使用sdf和sdf2調(diào)用parse()函數(shù)將字符串解析成Date類的對(duì)象date1和date2;
6)使用date1和date2對(duì)象調(diào)用getTime()函數(shù)獲取毫秒值t1和t2;
7)使用兩個(gè)毫秒值t1和t2相互相減,然后進(jìn)行算數(shù)運(yùn)算,得到結(jié)果并輸出即可;

package cn.xuexi.date.demo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
 * 練習(xí):"2014-08-09 09:09:09"  與  "2026年08/01 10:10:10"  相差多少月。
 */
public class SimpleDateFormatTest {
    public static void main(String[] args) {
        //創(chuàng)建格式化解析器對(duì)象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM/dd HH:mm:ss");
        //定義兩個(gè)字符串變量來(lái)保存日期
        String s1="2014-08-09 09:09:09";
        String s2="2026年08/01 10:10:10";
        //使用格式化解析器對(duì)象將上述字符串s1和s2解析成Date時(shí)間對(duì)象
        try {
            Date date1 = sdf.parse(s1);
            Date date2 = sdf2.parse(s2);
            //根據(jù)時(shí)間對(duì)象獲得毫秒值
            long time1 = date1.getTime();
            long time2 = date2.getTime();
            /*
             * 兩個(gè)時(shí)間相減 結(jié)果有可能為負(fù)數(shù),所以我們可以讓無(wú)論是正數(shù)還是負(fù)數(shù)都變成正數(shù)
             * Math.abs(time1-time2) 表示毫秒值相減的結(jié)果,而我們需要得知相差的月份
             * 所以得把毫秒值計(jì)算為月份
             */
            //long temp=Math.abs(time1-time2)/1000/60/60/24/365;//相差年份
               long temp=Math.abs(time1-time2)/1000/60/60/24/30;//相差月份
            System.out.println(temp);
        } catch (Exception e) {
            System.out.println("時(shí)間格式不對(duì)");
        }
    }
}

5、Calendar類介紹(掌握)

31.png

說(shuō)明:
1)Calendar類是一個(gè)抽象類,不能實(shí)例化對(duì)象。(需要通過(guò)方法獲取Calendar對(duì)象)


32.png

2)Calendar類屬于一個(gè)日歷類,記錄了一些生活中常用的日歷字段,比如年、月、日、時(shí)、分、秒等一些日期與時(shí)間的相關(guān)信息。

案例:Calendar類的使用。
分析和步驟:
1)創(chuàng)建一個(gè)CalendarDemo測(cè)試類;
2)在這個(gè)測(cè)試類的main函數(shù)中通過(guò)Calendar類調(diào)用getInstance()函數(shù)獲得日歷對(duì)象c;
3)輸出日歷對(duì)象c;

33.png

運(yùn)行結(jié)果:

34.png

注意:
1)在計(jì)算機(jī)中月份是從零開(kāi)始計(jì)算的。也就是說(shuō)數(shù)字0 表示1月,數(shù)字1表示2月,以此類推數(shù)字11表示12月。12表示下一年的1月;
2)一周中周日是第一天;
3)Calendar類中輸出結(jié)果是一些key-value對(duì)應(yīng)的信息。其實(shí)在Calendar對(duì)象內(nèi)部維護(hù)了一個(gè)Map集合,把當(dāng)前系統(tǒng)日期與時(shí)間上的所有信息全部使用key=value的形式保存在Calendar這個(gè)類中。

問(wèn)題:既然將當(dāng)前系統(tǒng)日期與時(shí)間上的所有信息全部存在了一個(gè)Map集合中,那么當(dāng)我們需要具體的什么信息時(shí),是否可以直接通過(guò)這個(gè)Calendar類來(lái)獲取,或者是否可以直接通過(guò)指定對(duì)應(yīng)的key,拿到當(dāng)前key對(duì)應(yīng)的value值呢?
答案是可以的。

使用Calendar類中的get(int field)函數(shù)就可以獲取Calendar對(duì)象中描述當(dāng)前時(shí)間數(shù)據(jù)。需要根據(jù)指定的key來(lái)獲取對(duì)應(yīng)的value。

35.png

注意:Calendar類是用來(lái)保存某個(gè)時(shí)間點(diǎn)上的所有和時(shí)間相關(guān)的數(shù)據(jù)。然后我們就可以通過(guò)Calendar類中的靜態(tài)成員變量作為key值(或者說(shuō)作為get()函數(shù)的參數(shù))來(lái)獲取其中的任何一個(gè)value數(shù)據(jù)。

案例:獲取Calendar對(duì)象中的日歷字段。(想要輸出” xxxx年xx月xx日”)
分析和步驟:
1)創(chuàng)建一個(gè)CalendarDemo1測(cè)試類;
2)在這個(gè)測(cè)試類的main函數(shù)中先創(chuàng)建Date類的對(duì)象d,通過(guò)對(duì)象d獲得當(dāng)前年、月、日,但是Date類中的函數(shù)都過(guò)期了;
3)通過(guò)Calendar類調(diào)用getInstance()函數(shù)獲得日歷對(duì)象c;
4)通過(guò)c對(duì)象調(diào)用get()函數(shù),Calendar.YEAR、Calendar.MONTH、Calendar.DAY_OF_MONTH依次作為函數(shù)的參數(shù)來(lái)獲得年、月(月份是從0開(kāi)始的到11,所以獲得月份需要+1)、日;
5)輸出獲得的年、月、日;

代碼如下所示:

package cn.xuexi.date.demo;
import java.util.Calendar;
import java.util.Date;
/*
 * 案例:獲取Calendar對(duì)象中的日歷字段。(想要輸出” xxxx年-xx月-xx日”)
 */
public class CalendarDemo1 {
    public static void main(String[] args) {
        // 創(chuàng)建時(shí)間日期類對(duì)象
        /*Date d = new Date();
        //獲得系統(tǒng)的年月日
        int year = d.getYear();//年 當(dāng)前系統(tǒng)時(shí)間減去1900
        int month = d.getMonth();//月 月份從0~11
        int day = d.getDate();//日 表示獲得一個(gè)月中的某一天
        //int day1 = d.getDay();//日 表示獲得一周中的某一天  0 表示星期日 1 表示星期一 2表示星期二
        //輸出Date類獲取的年月日
        System.out.println(year+"年"+month+"月"+day+"日");*/
        //Date日期類已經(jīng)過(guò)期了,被Calendar日歷類所取代了
        //創(chuàng)建日歷類Calendar類的對(duì)象
        Calendar c = Calendar.getInstance();//使用靜態(tài)方法獲取日歷對(duì)象
        //使用日歷對(duì)象c調(diào)用get函數(shù)獲得年份
        int year = c.get(Calendar.YEAR);//年
        int month = c.get(Calendar.MONTH)+1;//月份 從0開(kāi)始到11
        int day = c.get(Calendar.DAY_OF_MONTH);//一個(gè)月中的某一天
        System.out.println(year+"年"+month+"月"+day+"日");
    }
}

3)Calendar類的set()和add()函數(shù);

36.png

說(shuō)明:給當(dāng)前Calendar對(duì)象中的某個(gè)key設(shè)置value值。


37.png

說(shuō)明:是在當(dāng)前的時(shí)間點(diǎn)上添加某些時(shí)間。field 表示Calendar類中的成員變量,集合中key值。amount 表示當(dāng)前指定的數(shù)據(jù),這個(gè)數(shù)據(jù)可以是正數(shù),也可以是負(fù)數(shù)。正數(shù)代表著在當(dāng)前時(shí)間上加上amount 變量,負(fù)數(shù)代表著在當(dāng)前時(shí)間上減去amount 變量。

案例:Calendar類的set方法和add方法
分析和步驟:
1)創(chuàng)建一個(gè)CalendarDemo2測(cè)試類;
2)在這個(gè)測(cè)試類的main函數(shù)中通過(guò)Calendar類調(diào)用getInstance()函數(shù)獲得日歷對(duì)象c;
3)使用對(duì)象c調(diào)用set()函數(shù),并且Calendar.YEAR作為key,2011作為value來(lái)修改日歷字段中的年份;
4)使用對(duì)象c調(diào)用set()函數(shù)來(lái)設(shè)置日歷對(duì)象中的年月日;
5)使用對(duì)象c調(diào)用add()函數(shù),Calendar.MONTH作為key,1作為value在當(dāng)前日歷對(duì)象的基礎(chǔ)上增加一個(gè)月;
6)使用對(duì)象c調(diào)用add()函數(shù),Calendar.DAY_OF_MONTH作為key,-1作為value在當(dāng)前日歷對(duì)象的基礎(chǔ)上減少一天;
7)分別獲得年月日,并輸出獲得的年、月、日;

package cn.xuexi.date.demo;
import java.util.Calendar;
/*
 * 案例:Calendar類的set方法和add方法
 */
public class CalendarDemo2 {
    public static void main(String[] args) {
        // 使用靜態(tài)方法獲得日歷類對(duì)象
        Calendar c = Calendar.getInstance();
        //通過(guò)對(duì)象c調(diào)用set函數(shù)更改年
        //c.set(Calendar.YEAR, 2013);
        //更改日歷對(duì)象中的年月日
        //c.set(2012, 1, 1);
        //System.out.println(c);
        /*
         * 這里的月份13超出了月份的范圍11
         * 所以當(dāng)月份或者天數(shù)超出了所屬字段范圍后,會(huì)修改前面的日歷字段
         */
        //這里的月份13超出了月份的范圍11 結(jié)果是2013年2月1日 月份超出了范圍,修改年
        //c.set(2012, 13, 1);//2013年2月1日
        //這里的天數(shù)29超出了天數(shù)的范圍28  結(jié)果是2017年3月1日 天數(shù)超出了范圍,修改月
        c.set(2017, 1, 29);//2017年3月1日
        //使用日歷對(duì)象c調(diào)用add函數(shù)修改日歷中的數(shù)據(jù)
               //c.add(Calendar.MONTH, 1);//在當(dāng)前月份上加1個(gè)月
        c.add(Calendar.DAY_OF_MONTH, -1);//在當(dāng)前月的天數(shù)上減1
        //獲取年月日
        int year=c.get(Calendar.YEAR);//年
        int month=c.get(Calendar.MONTH)+1;//月
        int day=c.get(Calendar.DAY_OF_MONTH);//日
        //輸出
        System.out.println(year+"年"+month+"月"+day+"日");
    }
}

注意:
在使用set或add方法時(shí),如果設(shè)置的日歷字段超出當(dāng)前字段所屬范圍后,就會(huì)修改前面日歷字段的值:
1)月份超出了范圍,修改年;
2)天數(shù)超出了范圍,修改月;
3)如果日歷字段設(shè)置的值為負(fù)數(shù):就在當(dāng)前日歷字段的基礎(chǔ)上減;
4)如果日歷字段設(shè)置的值為正數(shù):就在當(dāng)前日歷字段的基礎(chǔ)上加;

面試題:
需求:使用最有效的方式獲取指定年份中2月的最大天數(shù)。
分析:一年中的二月份的天數(shù)有29天(閏年)或者28天(平年),也就是說(shuō)2月最大的天數(shù)要么是29,要么是28.
無(wú)論是29天還是28天,后一天肯定是3月1號(hào),那么我們可以先獲得一年中的3月1號(hào),然后在1號(hào)的基礎(chǔ)上減1,這樣就獲得了2月份的最大天數(shù)了。

分析和步驟:
1)創(chuàng)建CalendarTest類;
2)在CalendarTest類中使用Calendar調(diào)用getInstance()函數(shù)獲得日歷類的對(duì)象c;
3)使用日歷類對(duì)象c調(diào)用set()函數(shù)把時(shí)間設(shè)置成某一年的3月1日;
4)使用日歷類對(duì)象c調(diào)用add()函數(shù)把月中的天數(shù)-1;
5)日歷類對(duì)象c調(diào)用get()函數(shù)獲得年、月(月數(shù)+1)、日,并打??;

package cn.xuexi.date.demo;
import java.util.Calendar;
/*
 * 需求:使用最有效的方式獲取指定年份中2月的最大天數(shù)。
 */
public class CalendarTest {
    public static void main(String[] args) {
        // 根據(jù)靜態(tài)方法獲取日歷對(duì)象
        Calendar c = Calendar.getInstance();
        //使用日歷對(duì)象c調(diào)用set函數(shù)把日期設(shè)置到某一年的3月1號(hào)
        for (int year = 1000; year < 2020; year++) {
             //設(shè)置某一年的3月1日
            c.set(year, 2, 1);//計(jì)算機(jī)中的月份0~11
            //三月份天數(shù)倒退一天,就是減少一天
            c.add(Calendar.DAY_OF_MONTH, -1);
            // 獲取年月日
            int year2 = c.get(Calendar.YEAR);// 年
            int month = c.get(Calendar.MONTH) + 1;// 月
            int day = c.get(Calendar.DAY_OF_MONTH);// 日
            // 輸出
            System.out.println(year2 + "年" + month + "月" + day + "日");
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、Java 簡(jiǎn)介 Java是由Sun Microsystems公司于1995年5月推出的Java面向?qū)ο蟪绦蛟O(shè)計(jì)...
    子非魚_t_閱讀 4,654評(píng)論 1 44
  • 一、基礎(chǔ)知識(shí):1、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機(jī)...
    殺小賊閱讀 2,576評(píng)論 0 4
  • 2017.10.16今天是恩施店長(zhǎng)劉喜鳳二階畢業(yè)的日子,雖然沒(méi)有親臨現(xiàn)場(chǎng),但看著群里發(fā)來(lái)的視頻,內(nèi)心一陣陣小激動(dòng)!...
    麗華1117閱讀 212評(píng)論 3 1
  • 很多建站的朋友有時(shí)會(huì)忽略了網(wǎng)站的真正價(jià)值,完全沒(méi)有考慮過(guò)網(wǎng)站的優(yōu)化推廣,從而讓網(wǎng)站僅僅是一個(gè)擺設(shè),因此建站后也需要...
    萬(wàn)能的小二閱讀 1,395評(píng)論 0 0
  • 在百無(wú)聊賴的深夜,突然看到女兒上傳的圖片?!拔以谖绾笥鲆?jiàn)你”湛藍(lán)寥廓的天空,普通而疲憊的絕不美麗的蝴蝶...
    衣袂飄然閱讀 238評(píng)論 0 0

友情鏈接更多精彩內(nèi)容