最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的時間日期API知識點總結

 更新時間:2018年04月22日 11:11:30   投稿:laozhang  
本文給大家總結了Java中的時間日期API知識點以及相關的實例代碼分享,有興趣的朋友參考學習下。

自從 14 年發(fā)布 Java 8 以后,我們古老 java.util.Date 終于不再是我們 Java 里操作日期時間的唯一的選擇。

其實 Java 里的日期時間的相關 API 一直為世猿詬病,不僅在于它設計分上工不明確,往往一個類既能處理日期又能處理時間,很混亂,還在于某些年月日期的數(shù)值映射存儲反人類,例如:0 對應月份一月,11 對應月份十二月,118 對應年份 2018(1900 + 118)等。

往往我們得到某個年月值還需要再做相應的運算才能得到準確的年月日信息,直到我們的 Java 8 ,借鑒了第三方開源庫 Joda-Time 的優(yōu)秀設計,重新設計了一個日期時間 API,相比之前,可以說好用百倍,相關 API 接口全部位于包 java.time 下。

古老的日期時間接口

表示時刻信息的 Date

世界上所有的計算機內部存儲時間都使用一個 long 類型的整數(shù),而這個整數(shù)的值就是相對于英國格林尼治標準時間(1970年1月1日0時0分0秒)的毫秒數(shù)。例如:

public static void main(String[] args){
  //January 1, 1970 00:00:00 GMT.
  Date date = new Date(1000);
  System.out.println(date);
}

輸出結果:

//1970-1-1 8:00:01
Thu Jan 01 08:00:01 CST 1970

很多人可能會疑惑,1000 表示的是距離標準時間往后 1 秒,那為什么時間卻多走了 八個小時?

這和「時區(qū)」有關系,如果你位于英國的格林尼治區(qū),那么結果會如預想一樣,但是我們位于中國東八區(qū),時間要早八個小時,所以不同時區(qū)基于的基礎值不同。

Date 這個類以前真的扮演過很多角色,從它的源碼就可以看出來,有可以操作時刻的方法,有可以操作年月日的方法,甚至它還能管時區(qū)??梢哉f,日期時間的相關操作有它一個人就足夠了。

但這個世界就是這樣,你管的東西多了,自然就不能面面俱到,Date 中很多方法的設計并不是很合理,之前我們也說了,甚至有點反人類。所以,現(xiàn)在的 Date 類中接近百分之八十的方法都已廢棄,被標記為 @Deprecated。

sun 公司給 Date 的目前定位是,唯一表示一個時刻,所以它的內部應該圍繞著那個整型的毫秒,而不再著重于各種年歷時區(qū)等信息。

Date 允許通過以下兩種構造器實例化一個對象:

private transient long fastTime;

public Date() {
  this(System.currentTimeMillis());
}

public Date(long date) {
  fastTime = date;
}

這里的 fastTime 屬性存儲的就是時刻所對應的毫秒數(shù),兩個構造器還是很簡單,如果調用的是無參構造器,那么虛擬機將以系統(tǒng)當前的時刻值對 fastTime 進行賦值。

還有幾個為數(shù)不多沒有被廢棄的方法:

  • public long getTime() :返回內部存儲的毫秒數(shù)
  • public void setTime(long time):重新設置內存的毫秒數(shù)
  • public boolean before(Date when):比較給定的時刻是否早于當前 Date 實例
  • public boolean after(Date when):比較給定的時刻是否晚于當前 Date 實例

還有兩個方法是 jdk1.8 以后新增的,用于向 Java 8 新增接口的轉換,待會介紹。

 描述年歷的 Calendar

Calendar 用于表示年月日等日期信息,它是一個抽象類,所以一般通過以下四種工廠方法獲取它的實例對象。

public static Calendar getInstance()

public static Calendar getInstance(TimeZone zone)

public static Calendar getInstance(Locale aLocale)

public static Calendar getInstance(TimeZone zone,Locale aLocale)

其實內部最終會調用同一個內部方法:

private static Calendar createCalendar(TimeZone zone,Locale aLocale)

該方法需要兩個參數(shù),一個是時區(qū),一個是國家和語言,也就是說,構建一個 Calendar 實例最少需要提供這兩個參數(shù)信息,否則將會使用系統(tǒng)默認的時區(qū)或語言信息。

因為不同的時區(qū)與國家語言對于時刻和年月日信息的輸出是不同的,所以這也是為什么一個 Calendar 實例必須傳入時區(qū)和國家信息的一個原因??磦€例子:

public static void main(String[] args){


  Calendar calendar = Calendar.getInstance();
  System.out.println(calendar.getTime());

  Calendar calendar1 = Calendar.getInstance
      (TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
  System.out.println( calendar1.get(Calendar.YEAR) + ":" +
            calendar1.get(Calendar.HOUR) + ":" +
            calendar1.get(Calendar.MINUTE));
  }

輸出結果:

Sat Apr 21 10:32:20 CST 2018
2018:2:32

可以看到,第一個輸出為我們系統(tǒng)默認時區(qū)與國家的當前時間,而第二個 Calendar 實例我們指定了它位于格林尼治時區(qū)(0 時區(qū)),結果也顯而易見了,相差了八個小時,那是因為我們位于東八區(qū),時間早于 0 時區(qū)八個小時。

可能有人會疑惑了,為什么第二個 Calendar 實例的輸出要如此復雜的拼接,而不像第一個 Calendar 實例那樣直接調用 getTime 方法簡潔呢?

這涉及到 Calendar 的內部實現(xiàn),我們一起看看:

protected long     time;

public final Date getTime() {
  return new Date(getTimeInMillis());
}

和 Date 一樣,Calendar 的內部也維護著一個時刻信息,而 getTime 方法實際上是根據(jù)這個時刻構建了一個 Date 對象并返回的。

而一般我們構建 Calendar 實例的時候都不會傳入一個時刻信息,所以這個 time 的值在實例初始化的時候,程序會根據(jù)系統(tǒng)默認的時區(qū)和當前時間計算得到一個毫秒數(shù)并賦值給 time。

所以,所有未手動修改 time 屬性值的 Calendar 實例的內部,time 的值都是當時系統(tǒng)默認時區(qū)的時刻數(shù)值。也就是說,getTime 的輸出結果是不會理會當前實例所對應的時區(qū)信息的,這也是我覺得 Calendar 設計的一個缺陷所在,因為這樣會導致兩個不同時區(qū) Calendar 實例的 getTime 輸出值只取決于實例初始化時系統(tǒng)的運行時刻。

Calendar 中也定義了很多靜態(tài)常量和一些屬性數(shù)組:

public final static int ERA = 0;

public final static int YEAR = 1;

public final static int MONTH = 2;

public final static int WEEK_OF_YEAR = 3;

public final static int WEEK_OF_MONTH = 4;

public final static int DATE = 5;
....
protected int      fields[];

protected boolean    isSet[];
...

有關日期的所有相關信息都存儲在屬性數(shù)組中,而這些靜態(tài)常量的值往往表示的就是一個索引值,通過 get 方法,我們傳入一個屬性索引,返回得到該屬性的值。例如:

Calendar myCalendar = Calendar.getInstance();
int year = myCalendar.get(Calendar.YEAR);

這里的 get 方法實際上就是直接取的 fields[1] 作為返回值,而 fields 屬性數(shù)組在 Calendar 實例初始化的時候就已經(jīng)由系統(tǒng)根據(jù)時區(qū)和語言計算并賦值了,注意,這里會根據(jù)你指定的時區(qū)進行計算,它不像 time 始終是依照的系統(tǒng)默認時區(qū)。

個人覺得 Calendar 的設計有優(yōu)雅的地方,也有不合理的地方,畢竟是個「古董」了,終將被替代。

DateFormat 格式化轉換

從我們之前的一個例子中可以看到,Calendar 想要輸出一個預期格式的日期信息是很麻煩的,需要自己手動拼接。而我們的 DateFormat 就是用來處理格式化字符串和日期時間之間的轉換操作的。

DateFormat 和 Calendar 一樣,也是一個抽象類,我們需要通過工廠方式產(chǎn)生其實例對象,主要有以下幾種工廠方法:

//只處理時間的轉換
public final static DateFormat getTimeInstance()

//只處理日期的轉換
public final static DateFormat getDateInstance()

//既可以處理時間,也可以處理日期
public final static DateFormat getDateTimeInstance()

當然,它們各自都有各自的重載方法,具體的我們待會兒看。

DateFormat 有兩類方法,format 和 parse。

public final String format(Date date)

public Date parse(String source)

format 方法用于將一個日期對象格式化為字符串,parse 方法用于將一個格式化的字符串裝換為一個日期對象。例如:

public static void main(String[] args){
  Calendar calendar = Calendar.getInstance();
  DateFormat dateFormat = DateFormat.getDateTimeInstance();
  System.out.println(dateFormat.format(calendar.getTime()));
}

輸出結果:

2018-4-21 16:58:09

顯然,使用工廠構造的 DateFormat 實例并不能夠自定義輸出格式化內容,即輸出的字符串格式是固定的,不能滿足某些情況下的特殊需求。一般我們會直接使用它的一個實現(xiàn)類,SimpleDateFormat。

SimpleDateFormat 允許在構造實例的時候傳入一個 pattern 參數(shù),自定義日期字符的輸出格式。例如:

public static void main(String[] args){  
  DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
  System.out.println(dateFormat.format(new Date()));
}

輸出結果:

2018年04月21日

其中,

  • yyyy:年份用四位進行輸出
  • MM:月份用兩位進行輸出
  • dd:兩位表示日信息
  • HH:兩位來表示小時數(shù)
  • mm:兩位表示分鐘數(shù)
  • ss:兩位來表示秒數(shù)
  • E:表示周幾,如果 Locale 在中國則會輸出 星期x,如果在美國或英國則會輸出英文的星期
  • a:表示上午或下午

當然,對于字符串轉日期也是很方便的,允許自定義模式,但必須遵守自己制定的模式,否則程序將無法成功解析。例如:

public static void main(String[] args){
  String str = "2018年4月21日 17點17分 星期六";
  DateFormat sDateFormat = new SimpleDateFormat("yyyy年M月dd日 HH點mm分 E");
  sDateFormat.parse(str);
  System.out.println(sDateFormat.getCalendar().getTime());
}

輸出結果:

Sat Apr 21 17:17:00 CST 2018

顯然,程序是正確的解析的我們的字符串并轉換為 Calendar 對象存儲在 DateFormat 內部的。

總的來說,Date、Calendar 和 DateFormat 已經(jīng)能夠處理一般的時間日期問題了,但是不可避免的是,它們依然很繁瑣,不好用。

限于篇幅,我們下篇將對比 Java 8 的新式日期時間 API,你會發(fā)現(xiàn)它更加優(yōu)雅的設計和簡單的操作性。

相關文章

  • Jenkins一鍵打包部署SpringBoot應用的方法步驟

    Jenkins一鍵打包部署SpringBoot應用的方法步驟

    本文主要介紹了使用Jenkins一鍵打包部署SpringBoot應用的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Java深入淺出數(shù)組的定義與使用下篇

    Java深入淺出數(shù)組的定義與使用下篇

    數(shù)組是有序的元素序列,若將有限個類型相同的變量的集合命名,那么這個名稱為數(shù)組名。組成數(shù)組的各個變量稱為數(shù)組的分量,也稱為數(shù)組的元素,有時也稱為下標變量。數(shù)組是在程序設計中,為了處理方便,?把具有相同類型的若干元素按有序的形式組織起來的一種形式
    2022-03-03
  • 實例講解String Date Calendar之間的轉換

    實例講解String Date Calendar之間的轉換

    下面小編就為大家?guī)硪黄獙嵗v解String Date Calendar之間的轉換。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • Java多線程繼承Thread類詳解

    Java多線程繼承Thread類詳解

    Java多線程的兩種實現(xiàn)方式:繼承Thread類 & 實現(xiàn)Runable接口,今天我們來學習下繼承Thread類,希望大家能夠喜歡
    2016-06-06
  • 解決java.lang.IllegalStateException:Duplicate key異常問題

    解決java.lang.IllegalStateException:Duplicate key異常問題

    java.lang.IllegalStateException:Duplicatekey異常在將List轉換為Map時出現(xiàn),解決方法是使用toMap()的重載方法,如果已經(jīng)存在則不再修改,直接使用上一個數(shù)據(jù)
    2025-03-03
  • Java文件、文件夾權限修改的兩種方法

    Java文件、文件夾權限修改的兩種方法

    這篇文章主要給大家介紹了關于Java文件、文件夾權限修改的兩種方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-08-08
  • SpringBoot JPA懶加載失效的解決方案(親測有效)

    SpringBoot JPA懶加載失效的解決方案(親測有效)

    這篇文章主要介紹了SpringBoot JPA懶加載失效的解決方案(親測有效),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • android中GridView的用法示例

    android中GridView的用法示例

    這篇文章主要介紹了android中GridView的用法,對于Android初學者很有參考學習價值,需要的朋友可以參考下
    2014-08-08
  • 深入了解JVM(Java虛擬機)內存結構

    深入了解JVM(Java虛擬機)內存結構

    Java虛擬機(Java Virtual Machine,JVM)是Java程序的運行環(huán)境,它是一個抽象的計算機模型,通過解釋和執(zhí)行Java字節(jié)碼來運行Java程序,本將大家深入了解JVM(Java虛擬機)內存結構,需要的朋友可以參考下
    2023-08-08
  • SpringBoot Pom文件依賴及Starter啟動器詳細介紹

    SpringBoot Pom文件依賴及Starter啟動器詳細介紹

    這篇文章主要介紹了SpringBoot Pom文件的依賴與starter啟動器的作用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-09-09

最新評論

巨野县| 乡城县| 邯郸市| 临潭县| 休宁县| 南康市| 武川县| 昭通市| 铜陵市| 景宁| 乌鲁木齐县| 德江县| 贵州省| 宜都市| 德州市| 图木舒克市| 喀喇沁旗| 江华| 嘉荫县| 甘泉县| 明星| 万年县| 东阿县| 临桂县| 轮台县| 介休市| 奉新县| 浠水县| 东莞市| 建始县| 神农架林区| 突泉县| 龙南县| 阜新| 库伦旗| 宝坻区| 灵山县| 宣武区| 龙胜| 泰和县| 波密县|