<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java 中的時(shí)間處理

          共 5228字,需瀏覽 11分鐘

           ·

          2021-02-02 02:30

          最初學(xué)習(xí) Java 時(shí)是采用學(xué)校教材和市面上的一些 Java 視頻教程進(jìn)行學(xué)習(xí),到了工作中才發(fā)現(xiàn)有些 API 或包已經(jīng)過(guò)時(shí)了。最近使用 Java 中的日期處理時(shí)發(fā)現(xiàn) java.util.date 與 Calender 相關(guān)包官方已經(jīng)逐漸棄用,因此總結(jié)一下目前 Java 中的日期處理方式。

          首先先了解一下為什么 Java 8 之前的日期處理方式為什么難用。對(duì)大多數(shù)初學(xué)者最熟悉的 日期處理方式就是 Java 1中的 java.util.Date 類,這個(gè)類年份起始選擇是 1900 年,月份起始從 0 開(kāi)始。

          Date date = new Date( 2020, 2, 18);

          它的打印效果如下:

          Tue Mar 18 00: 00: 00 CET 2020

          但它并不直觀,他默認(rèn)返回計(jì)算機(jī)格式的日期。你需要將它轉(zhuǎn)換為我們?nèi)菀撰@取的特定格式,需要使用 java.text.SimpleDateFormat 類進(jìn)行格式轉(zhuǎn)化,但這個(gè)類不是線程安全的,多線程格式轉(zhuǎn)化需要使用同步代碼塊加鎖解決線程安全問(wèn)題。

          隨后 Java 1.1 出現(xiàn)了 java.util.Calender 類,但 Calender 類也有涉及缺陷,比如月份也是從 0 開(kāi)始。許多新手在選擇日期處理方式時(shí)會(huì)不知道用哪種,新手在使用 Date 與 Calender 的過(guò)程中會(huì)出現(xiàn)各種難以預(yù)料的錯(cuò)誤,調(diào)試搜索后才會(huì)發(fā)現(xiàn)原來(lái)是設(shè)計(jì)上的缺陷。

          直到 Java 8 才出現(xiàn)了目前正在使用的新的日期和時(shí)間庫(kù) java.time.xxx。

          Java ?中的最新的日期處理方式

          目前網(wǎng)上搜索的 Java 日期處理最多的返回結(jié)果還是 Date 、Calender 類型的問(wèn)題,我也是因?yàn)椴冗^(guò)日期處理的許多坑才發(fā)現(xiàn)自己的知識(shí)已經(jīng)過(guò)時(shí),我相信跟我一樣的工程師不在少數(shù)。

          為什么我定義 Java 8 中的日期處理方式是最新的呢,因?yàn)?Java 11 等后續(xù)版本一直在沿用 Java 8 的日期處理方式。Java 8 中出現(xiàn)了新的日期創(chuàng)建與時(shí)間間隔的類。分別是 LocalDate 、LocalTime 、Instant 、Duration 和 Period 。

          我將參考 Java 11 的 java.time 文檔講解這些日期處理方式。

          使用 LocalDate 、 LocalTime 與 LocalDateTime

          LocalDate 存儲(chǔ)沒(méi)有時(shí)間的日期。它存儲(chǔ)的日期類似于 “2010-12-03” ,可以用來(lái)存儲(chǔ)生日。

          LocalDate 可以創(chuàng)建 ISO-8601日歷系統(tǒng)中沒(méi)有時(shí)區(qū)的日期,如 2007-12-03。LocalDate 是一個(gè)不可變的日期-時(shí)間對(duì)象,表示日期,通常格式為年-月-日。如下代碼創(chuàng)建一個(gè)LocalDate 對(duì)象并實(shí)驗(yàn)其方法。

          LocalDate date = LocalDate.of( 2014, 3, 18); // 2014-03-18 

          int year = date.getYear(); // 2014

          Month month = date.getMonth();// MARCH

          int day = date.getDayOfMonth();// 18

          DayOfWeek dow = date.getDayOfWeek();// TUESDAY

          int len = date.lengthOfMonth(); // 31 (三月的天數(shù))

          boolean leap = date.isLeapYear(); // false 不是閏年

          LocalDate today = LocalDate.now();
          // 從系統(tǒng)時(shí)鐘中獲取當(dāng)前的日期

          // 使用TemporalField 讀取LocalDate 的值

          int year = date.get( ChronoField.YEAR);

          int month = date.get( ChronoField.MONTH_OF_YEAR);

          int day = date.get( ChronoField.DAY_OF_MONTH);

          一天中的時(shí)間,可以用 LocalTime 來(lái)表示,LocalTime 存儲(chǔ)沒(méi)有日期的時(shí)間。這種存儲(chǔ)時(shí)間格式為 “11:30”,可以用來(lái)存儲(chǔ)營(yíng)業(yè)的時(shí)間。LocalTime 是一個(gè)不可變的日期-時(shí)間對(duì)象,它表示時(shí)間,通常被視為小時(shí)-分鐘-秒。時(shí)間以納秒精度表示。

          LocalTime time = LocalTime.of( 13, 45, 20); // 13: 45: 20 

          int hour = time.getHour(); // 13
          int minute = time.getMinute(); // 45
          int second = time.getSecond();// 20

          LocalDateTime 是 ISO-8601日歷系統(tǒng)中不帶時(shí)區(qū)的日期-時(shí)間,如2007-12-03T10:15:30。LocalDateTime是一個(gè)不可變的日期-時(shí)間對(duì)象,它表示一個(gè)日期-時(shí)間,通常被視為年-月-日-時(shí)-分-秒。還可以訪問(wèn)其他日期和時(shí)間字段,如 day-of-year、day-of-week 和 week-of-year。

          // 2014-03-18T13: 45: 20 
          LocalDateTime dt1 = LocalDateTime.of( 2014, Month.MARCH, 18, 13, 45, 20);
          LocalDateTime dt2 = LocalDateTime.of( date, time);
          LocalDateTime dt3 = date.atTime( 13, 45, 20);
          LocalDateTime dt4 = date.atTime( time);
          LocalDateTime dt5 = time.atDate( date);

          // 提取日期和時(shí)間
          LocalDate date1 = dt1. toLocalDate(); // 2014-03-18
          LocalTime time1 = dt1. toLocalTime(); // 13: 45: 20



          ZonedDateTime 的使用

          ZonedDateTime ?ISO-8601日歷系統(tǒng)中帶有時(shí)區(qū)的日期-時(shí)間,例如 2007-12-03T10:15:30+01:00 Europe/Paris. 我們可以從下圖看出 LocalDate、LocalTime、LocalDateTime 、ZonedDateTime 的區(qū)別。



          ZoneId romeZone = ZoneId.of("Europe/ Rome");

          LocalDate date = LocalDate.of( 2014, Month.MARCH, 18);
          ZonedDateTime zdt1 = date.atStartOfDay( romeZone);

          LocalDateTime dateTime = LocalDateTime.of( 2014, Month.MARCH, 18, 13, 45);
          ZonedDateTime zdt2 = dateTime.atZone( romeZone);

          Instant instant = Instant.now();
          ZonedDateTime zdt3 = instant.atZone( romeZone);

          ZoomId 對(duì)應(yīng)的Map選項(xiàng)可以從官方文檔中查看 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZoneId.html

          LocalDate 與 LocalTime 與字符串格式轉(zhuǎn)化

          LocalDate date = LocalDate.parse("2014-03-18"); 
          LocalTime time = LocalTime.parse("13: 45: 20");

          我們可以使用指定的 fomatter 程序格式化日期, java.time.format.DateTimeFormatter 提供了兩個(gè)方法:一個(gè)用于格式化,format(DateTimeFormatter formatter),另一個(gè)用于解析,parse(CharSequence text, DateTimeFormatter formatter)。

           LocalDate date = LocalDate.now();
          String text = date.format(formatter);
          LocalDate parsedDate = LocalDate.parse(text, formatter);

          LocalDate date = LocalDate.now();
          DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
          String text = date.format(formatter);
          LocalDate parsedDate = LocalDate.parse(text, formatter);

          LocalDate date = LocalDate.of( 2014, 3, 18);
          String s1 = date.format( DateTimeFormatter.BASIC_ISO_DATE); //20140318
          String s2 = date.format( DateTimeFormatter.ISO_LOCAL_DATE); //2014-03-18

          LocalDate date1 = LocalDate.parse(" 20140318", DateTimeFormatter.BASIC_ISO_DATE);
          LocalDate date2 = LocalDate.parse(" 2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE);

          Duration 與 Period

          Duration 一個(gè)基于時(shí)間的時(shí)間量,例如'34.5秒'。

          它的 between 方法可以計(jì)算兩個(gè) LocalDateTime 或 兩個(gè) LocalTime 或兩個(gè) Instance 之間的間隔。

          Duration d1 = Duration.between( time1, time2); 
          Duration d1 = Duration.between( dateTime1, dateTime2);
          Duration d2 = Duration.between( instant1, instant2);

          注意 Instance (時(shí)間線上的瞬間點(diǎn))這個(gè)類記錄時(shí)間線上的單個(gè)瞬時(shí)點(diǎn),常在應(yīng)用程序中記錄事件時(shí)間戳。

          // 從系統(tǒng)時(shí)鐘中獲取當(dāng)前時(shí)刻。
          Instant.now();

          Period 是 ISO-8601日歷系統(tǒng)中基于日期的時(shí)間量,例如“2年、3個(gè)月和4天”。

          Period tenDays = Period.between( LocalDate.of( 2014, 3, 8), LocalDate.of( 2014, 3, 18));

          Duration threeMinutes = Duration.ofMinutes(3);
          Duration threeMinutes = Duration.of(3, ChronoUnit.MINUTES);

          Period tenDays = Period.ofDays(10);
          Period threeWeeks = Period.ofWeeks(3);
          Period twoYearsSixMonthsOneDay = Period.of(2,6,1);

          創(chuàng)建好 Period 和 Duration 對(duì)象后,我們可以使用他們定義好的各種方法查詢兩個(gè)日期之間的時(shí)間差,用于后續(xù)處理邏輯。

          總結(jié)

          Java 中的日期處理方式目前采用 LocalDate、LocalTime、LocalDateTime,應(yīng)該逐漸拋棄以前的 Date 與 Calender 方式。

          參考資料

          • 《Java 8實(shí)戰(zhàn)》 。人民郵電出版社.。[英]厄馬(Raoul-Gabriel Urma)[意] 弗斯科(Mario Fusco)[英] 米克羅夫特(Alan Mycroft).

          • Java 11 官方文檔


          瀏覽 54
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本免费成人撸一区二区三区 | 美女大香蕉久久 | 成人艳史成人版 | 日韩黄色免费网站 | 国产嫩草影院久久久久 |