91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java8中時間的使用方法

發布時間:2020-10-19 16:07:34 來源:億速云 閱讀:113 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關java8中時間的使用方法的內容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。

為什么需要新的時間API?

在Java 8之前的日期/時間API之前,現有的與日期和時間相關的類存在諸多問題,其中主要有:

  1. Java的日期/時間類的定義并不一致,在java.util和java.sql的包中都有日期類,此外用于格式化和解析的類在java.text包中定義

  2. java.util.Date同時包含日期和時間,而java.sql.Date僅包含日期,將其納入java.sql包并不合理。另外這兩個類都有相同的名字,這本身就是一個非常糟糕的設計。

  3. 對于時間、時間戳、格式化以及解析,并沒有一些明確定義的類。對于格式化和解析的需求,我們有java.text.DateFormat抽象類,但通常情況下,SimpleDateFormat類被用于此類需求。

  4. 所有的日期類都是可變的,因此他們都不是線程安全的,這是Java日期類最大的問題之一。

  5. 日期類并不提供國際化,沒有時區支持,因此Java引入了java.util.Calendar和java.util.TimeZone類,但他們同樣存在上述所有的問題。

  6. 在現有的日期和日歷類中定義的方法還存在一些其他的問題,但以上問題已經很清晰地表明:Java需要一個健壯的日期/時間類。這也是為什么Joda Time在Java日期/時間需求中扮演了高質量替換的重要角色。

  7. 使用java8之前的日期注意

   使用Calendar類實現日期和時間字段之間轉換
   使用DateFormat類來格式化和分析日期字符串
   而Date只用來承載日期和時間信息

java8 概念

瞬時時間(Instant),持續時間(duration),日期(date),時間(time),時區(time-zone)以及時間段(Period)。Java 8仍然延用了ISO的日歷體系,并且與它的前輩們不同,java.time包中的類是不可變且線程安全的。新的時間及日期API位于java.time包中,下面是里面的一些關鍵的類:

  • Instant——它代表的是時間戳(因為它代表了一個確定的時間點,即相對于1970年1月1日的偏移量;但與java.util.Date類不同的是其精確到了納秒級別。

  • Duration:持續時間,時間差

  • LocalDate——不包含具體時間的日期,比如2019-01-14。它可以用來存儲生日,周年紀念日,入職日期等。

  • LocalTime——它代表的是不含日期的時間

  • LocalDateTime——它包含了日期及時間,不過還是沒有偏移信息或者說時區。

  • Period:時間段

  • ZoneOffset:時區偏移量,比如:+8:00

  • ZonedDateTime——這是一個包含時區的完整的日期時間,偏移量是以UTC/格林威治時間為基準的。

  • Clock:時鐘,比如獲取目前美國紐約的時間

java8時間API特性

  • 不變性:新的日期/時間API中,所有的類都是不可變的,這對多線程很有好處。

  • 關注點分離:借鑒了Joda庫的一些優點,新的API將人可讀的日期時間和機器時間(unix timestamp)明確分離,它為日期(Date)、時間(Time)、日期時間(DateTime)、時間戳(unix timestamp)以及時區定義了不同的類。

  • 清晰:在所有的類中,方法都被明確定義用以完成相同的行為。例如要拿到當前實例我們可以使用now()方法,在所有的類中都定義了format()和parse()方法,而不是像以前那樣專門有一個獨立的類。為了更好的處理問題,所有的類都使用了工廠模式和策略模式,一旦你使用了其中某個類的方法,與其他類協同工作并不困難。

  • 實用操作:所有新的日期/時間API類都實現了一系列方法用以完成通用的任務,如:加、減、格式化、解析、從日期/時間中提取單獨部分,等等。

  • 可擴展性:新的日期/時間API是工作在ISO-8601日歷系統上的,但我們也可以將其應用在非IOS的日歷上。

java8日期/時間API包

  • java.time包:這是新的Java日期/時間API的基礎包,所有的主要基礎類都是這個包的一部分,如:LocalDate, LocalTime, LocalDateTime, Instant, Period, Duration等等。所有這些類都是不可變的和線程安全的,在絕大多數情況下,這些類能夠有效地處理一些公共的需求。

  • java.time.chrono包:這個包為非ISO的日歷系統定義了一些泛化的API,我們可以擴展AbstractChronology類來創建自己的日歷系統。

  • java.time.format包:這個包包含能夠格式化和解析日期時間對象的類,在絕大多數情況下,我們不應該直接使用它們,因為java.time包中相應的類已經提供了格式化和解析的方法。

  • java.time.temporal包:這個包包含一些時態對象,我們可以用其找出關于日期/時間對象的某個特定日期或時間,比如說,可以找到某月的第一天或最后一天。你可以非常容易地認出這些方法,因為它們都具有“withXXX”的格式。

  • java.time.zone包:這個包包含支持不同時區以及相關規則的類。

java8 API介紹和使用

LocalDate

LocalDate 依然是一個不可變類,它關注時間中年月日部分

初始化實例
public static LocalDate now():截斷當前系統時間的年月日信息并初始化一個實例對象
public static LocalDate of(int year, int month, int dayOfMonth):顯式指定年月日信息
public static LocalDate ofYearDay(int year, int dayOfYear):根據 dayOfYear 可以推出 month 和 dayOfMonth
public static LocalDate ofEpochDay(long epochDay):相對于格林零時區時間的日偏移量
…………

示例

// 取當前日期:
LocalDate today = LocalDate.now(); // -> 2019-01-31
// 根據年月日取日期,12月就是12:
LocalDate crischristmas = LocalDate.of(2018, 12, 25); // -> 2018-12-25
// 根據字符串取:
LocalDate endOfFeb = LocalDate.parse("2018-12-25"); // 嚴格按照ISO yyyy-MM-dd驗證,02寫成2都不行,當然也有一個重載方法允許自己定義格式

// 如何獲取1周后的日期
LocalDate oneToday = today.plus(1, ChronoUnit.WEEKS); // ->2019-02-07
//一年前的日期
LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);
// 取本月第1天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 2019-01-01
// 取本月第2天:
LocalDate secondDayOfThisMonth = today.withDayOfMonth(2); // 2019-01-02
// 取本月最后一天,再也不用計算是28,29,30還是31:
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); // 2019-01-31
// 取下一天:
LocalDate firstDay = lastDayOfThisMonth.plusDays(1); // 變成了2019-02-01
// 取2019年1月第一個周一
LocalDate firstMonday = LocalDate.parse("2019-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); // 2019-01-07

在java8中,可以使用MonthDay,該類不包含年份信息,當然還有一個類是YearMonth

LocalDate birthday = LocalDate.of(1990, 10, 12);
MonthDay birthdayMd = MonthDay.of(birthday.getMonth(), birthday.getDayOfMonth());
MonthDay today = MonthDay.from(LocalDate.of(2019, 10, 12)); 
System.out.println(today.equals(birthdayMd));
//結果
true
TemporalAdjuster

但是有些時候我們要面臨更復雜的時間操作,比如將時間調到下一個工作日,或者是下個月的最后一天,這時候我們可以使用with()方法的另一個重載方法,它接收一個TemporalAdjuster參數,可以使我們更加靈活的調整日期:

LocalDate date7 = date.with(nextOrSame(DayOfWeek.SUNDAY));      // 返回下一個距離當前時間最近的星期日
LocalDate date9 = date.with(lastInMonth(DayOfWeek.SATURDAY));   // 返回本月最后一個星期六

如果本身API不滿足你的需求,你還可以創建自定義的TemporalAdjuster接口的實現

LocalTime

類似于 LocalDate,LocalTime 專注于時間的處理,它提供小時,分鐘,秒,毫微秒的各種處理

初始化LocalTime實例
public static LocalTime now():根據系統當前時刻獲取其中的時間部分內容
public static LocalTime of(int hour, int minute):顯式傳入小時和分鐘來構建一個實例對象
public static LocalTime of(int hour, int minute, int second):通過傳入時分秒構造實例
public static LocalTime of(int hour, int minute, int second, int nanoOfSecond):傳入時分秒和毫微秒構建一個實例
public static LocalTime ofSecondOfDay(long secondOfDay):傳入一個長整型數值代表當前日已經過去的秒數
public static LocalTime ofNanoOfDay(long nanoOfDay):傳入一個長整型代表當前日已經過去的毫微秒數

示例

//包含毫秒
LocalTime now = LocalTime.now(); // 11:09:09.240
//不包含毫秒  
LocalTime now = LocalTime.now().withNano(0)); // 11:09:09
//構造時間  
LocalTime zero = LocalTime.of(0, 0, 0); // 00:00:00
LocalTime mid = LocalTime.parse("12:00:00"); // 12:00:00
LocalTime twoHour = now.plusHours(2);

LocalDateTime

LocalDateTime類是LocalDate和LocalTime的結合體,可以通過of()方法直接創建,也可以調用LocalDate的atTime()方法或LocalTime的atDate()方法將LocalDate或LocalTime合并成一個LocalDateTime

LocalDateTime ldt1 = LocalDateTime.of(2017, Month.JANUARY, 4, 17, 23, 52);

LocalDate localDate = LocalDate.of(2017, Month.JANUARY, 4);
LocalTime localTime = LocalTime.of(17, 23, 52);
LocalDateTime ldt2 = localDate.atTime(localTime);

LocalDateTime也提供用于向LocalDate和LocalTime的轉化:

LocalDate date = ldt1.toLocalDate();
LocalTime time = ldt1.toLocalTime();

Instant

Instant用于表示一個時間戳,它與我們常使用的System.currentTimeMillis()有些類似,不過Instant可以精確到納秒(Nano-Second),System.currentTimeMillis()方法只精確到毫秒(Milli-Second)。如果查看Instant源碼,發現它的內部使用了兩個常量,seconds表示從1970-01-01 00:00:00開始到現在的秒數,nanos表示納秒部分(nanos的值不會超過999,999,999)。Instant除了使用now()方法創建外,還可以通過ofEpochSecond方法創建:

Instant instant = Instant.ofEpochSecond(120, 100000);

時間差

關于時間差的計算,主要涉及到兩個類,年月日的日期間差值的計算使用 Period 類足以,而時分秒毫秒的時間的差值計算則需要使用Duration類。

  • Duration:處理兩個時間之間的差值

        LocalDateTime from = LocalDateTime.of(2019, Month.JANUARY, 5, 10, 7, 0);    // 2019-01-05 10:07:00
    LocalDateTime to = LocalDateTime.of(2019, Month.FEBRUARY, 5, 10, 7, 0);     // 2019-02-05 10:07:00
    Duration duration = Duration.between(from, to);     // 表示從 2019-01-05 10:07:00 到 2019-02-05 10:07:00 這段時間
    
    long days = duration.toDays();              // 這段時間的總天數
    long hours = duration.toHours();            // 這段時間的小時數
    long minutes = duration.toMinutes();        // 這段時間的分鐘數
    long seconds = duration.getSeconds();       // 這段時間的秒數
    long milliSeconds = duration.toMillis();    // 這段時間的毫秒數
    long nanoSeconds = duration.toNanos();      // 這段時間的納秒數

    Duration對象還可以通過of()方法創建,該方法接受一個時間段長度,和一個時間單位作為參數:

    Duration duration1 = Duration.of(5, ChronoUnit.DAYS);       // 5天
    Duration duration2 = Duration.of(1000, ChronoUnit.MILLIS);  // 1000毫秒
    • Duration的內部實現與Instant類似,也是包含兩部分:seconds表示秒,nanos表示納秒。兩者的區別是Instant用于表示一個時間戳(或者說是一個時間點),而Duration表示一個時間段,所以Duration類中不包含now()靜態方法。可以通過Duration.between()方法創建

  • Period:處理兩個日期之間的差值

    • Period在概念上和Duration類似,區別在于Period是以年月日來衡量一個時間段,比如2年3個月6天

      Period period = Period.of(2, 3, 6);
  • Period對象也可以通過between()方法創建,值得注意的是,由于Period是以年月日衡量時間段,所以between()方法只能接收LocalDate類型的參數:

    Period period = Period.between(
                LocalDate.of(2019, 1, 5),
                LocalDate.of(2019, 2, 5));
  • 示例

 LocalDate date = LocalDate.of(2019,01,22);
    LocalDate date1 = LocalDate.now();
    Period period = Period.between(date,date1);
    System.out.println(period.getYears() + "年" +
            period.getMonths() + "月" +
            period.getDays() + "天");

    LocalTime time = LocalTime.of(20,30);
    LocalTime time1 = LocalTime.of(23,59);
    Duration duration = Duration.between(time,time1);
    System.out.println(duration.toMinutes() + "分鐘");

ZonedDateTime

無論是我們的 LocalDate,或是 LocalTime,甚至是 LocalDateTime,它們基本是時區無關的,內部并沒有存儲時區屬性,而基本用的系統默認時區。往往有些場景之下,缺乏一定的靈活性。

ZonedDateTime 可以被理解為 LocalDateTime 的外層封裝,它的內部存儲了一個 LocalDateTime 的實例,專門用于普通的日期時間處理。此外,它還定義了 ZoneId 和 ZoneOffset 來描述時區的概念。

ZonedDateTime 和 LocalDateTime 的一個很大的不同點在于,后者內部并沒有存儲時區,所以對于系統的依賴性很強,往往換一個時區可能就會導致程序中的日期時間不一致。
而后者則可以通過傳入時區的名稱,使用 ZoneId 進行匹配存儲,也可以通過傳入與零時區的偏移量,使用 ZoneOffset 存儲時區信息。

初始化實例
public static ZonedDateTime now():系統將以默認時區計算并存儲日期時間信息
public static ZonedDateTime now(ZoneId zone):指定時區
public static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone):指定日期時間和時區
public static ZonedDateTime of(LocalDateTime localDateTime, ZoneId zone)
public static ZonedDateTime ofInstant(Instant instant, ZoneId zone):通過時刻和時區構建實例對象
等等

示例

 ZonedDateTime zonedDateTime = ZonedDateTime.now();
    System.out.println(zonedDateTime); 
    //->2019-01-31T16:27:23.179+08:00[Asia/Shanghai]

    LocalDateTime localDateTime = LocalDateTime.now();
    ZoneId zoneId = ZoneId.of("America/Los_Angeles");
    ZonedDateTime zonedDateTime1 = ZonedDateTime.of(localDateTime,zoneId);
    System.out.println(zonedDateTime1);
    // ->2019-01-31T16:27:23.179-08:00[America/Los_Angeles]


    Instant instant = Instant.now();
    ZoneId zoneId1 = ZoneId.of("GMT");
    ZonedDateTime zonedDateTime2 = ZonedDateTime.ofInstant(instant,zoneId1);
    System.out.println(zonedDateTime2);
    // ->2019-01-31T08:27:23.183Z[GMT]
  • 第一個輸出應使用了當前系統日期和時間以及默認的時區。

  • 第二個小例子,LocalDateTime 實例保存了時區無關的當前日期時間信息,也就是這里的年月日時分秒,接著構建一個 ZonedDateTime 實例并傳入一個美國時區(西七區)。你會發現輸出的日期時間為西七區的 16 點 27 分。

    像這種關聯了時區的日期時間就很能夠解決那種,換時區導致程序中時間錯亂的問題。因為我關聯了時區,無論你程序換到什么地方運行了,日期+時區 本就已經唯一確定了某個時刻,就相當于我在存儲某個時刻的時候,說明了這是某某時區的某某時間,即便你換了一個地區,也不至于把這個時間按自己當前的時區進行解析并直接使用。

  • 第三個小例子,構建 ZonedDateTime實例的時候,給定一個時刻和一個時區,而這個時刻值就是相對于給定時區的標準時間所經過的毫秒數。

    有關 ZonedDateTime 的其他日期時間的處理方法和 LocalDateTime 是一樣的,因為 ZonedDateTime 是直接封裝了一個 LocalDateTime 實例對象,所以所有相關日期時間的操作都會間接的調用 LocalDateTime 實例的方法,我們不再贅述。

格式化日期時間

Java 8 的新式日期時間 API 中,DateTimeFormatter 作為格式化日期時間的主要類,它與之前的 DateFormat 類最大的不同就在于它是線程安全的,如果需要的話,可以賦值給一個靜態變量。

DateTimeFormatter類提供了許多預定義的格式器,你也可以自定義自己想要的格式。當然根據約定,它還有一個parse()方法是用于將字符串轉換成日期的,如果轉換期間出現任何錯誤,它會拋出DateTimeParseException異常。類似的,DateFormatter類也有一個用于格式化日期的format()方法,它出錯的話則會拋出DateTimeException異常

再說一句,“MMM d yyyy”與“MMm dd yyyy”這兩個日期格式也略有不同,前者能識別出"Jan 2 2018"與"Jan 14 2018"這兩個串,而后者如果傳進來的是"Jan 2 2018"則會報錯,因為它期望月份處傳進來的是兩個字符。為了解決這個問題,在天為個位數的情況下,你得在前面補0,比如"Jan 2 2018"應該改為"Jan 02 2018"。

public static void main(String[] a){
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
    LocalDateTime localDateTime = LocalDateTime.now();
    System.out.println(formatter.format(localDateTime));

    String str = "2008年08月23日 23:59:59";
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
    LocalDateTime localDateTime2 = LocalDateTime.parse(str,formatter2);
    System.out.println(localDateTime2);

}

java8 時間與老版本時間轉換

因為java8之前Date是包含日期和時間的,而LocalDate只包含日期,LocalTime只包含時間,所以與Date在互轉中,勢必會丟失日期或者時間,或者會使用起始時間。如果轉LocalDateTime,那么就不存在信息誤差。

/Date與Instant的相互轉化
Instant instant  = Instant.now();
Date date = Date.from(instant);
Instant instant2 = date.toInstant();
        
//Date轉為LocalDateTime
Date date2 = new Date();
LocalDateTime localDateTime2 = LocalDateTime.ofInstant(date2.toInstant(), ZoneId.systemDefault());
        
//LocalDateTime轉Date
LocalDateTime localDateTime3 = LocalDateTime.now();
Instant instant3 = localDateTime3.atZone(ZoneId.systemDefault()).toInstant();
Date date3 = Date.from(instant);

//LocalDate轉Date
//因為LocalDate不包含時間,所以轉Date時,會默認轉為當天的起始時間,00:00:00
LocalDate localDate4 = LocalDate.now();
Instant instant4 = localDate4.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date date4 = Date.from(instant);


// Calendar to Instant
Instant time = Calendar.getInstance().toInstant();
System.out.println(time);

// TimeZone to ZoneId
ZoneId defaultZone = TimeZone.getDefault().toZoneId();
System.out.println(defaultZone);
 
// ZonedDateTime from specific Calendar
ZonedDateTime gregorianCalendarDateTime = new GregorianCalendar().toZonedDateTime();
System.out.println(gregorianCalendarDateTime);
 
 
GregorianCalendar gc = GregorianCalendar.from(gregorianCalendarDateTime);
System.out.println(gc);

感謝各位的閱讀!關于java8中時間的使用方法就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

闽清县| 黎川县| 呼和浩特市| 宜宾县| 岗巴县| 石泉县| 鄢陵县| 通许县| 唐海县| 宁安市| 五峰| 新安县| 南涧| 柳州市| 循化| 河北省| 济源市| 彝良县| 竹北市| 体育| 寿宁县| 湖州市| 桐庐县| 和龙市| 敦化市| 临武县| 灵丘县| 民和| 诏安县| 榆树市| 弥勒县| 石首市| 馆陶县| 安岳县| 河东区| 乐山市| 临泉县| 云阳县| 平定县| 信丰县| 南澳县|