国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性

這篇具有很好參考價(jià)值的文章主要介紹了【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本系列為:從零開始學(xué)Java,為千鋒教育資深Java教學(xué)老師獨(dú)家創(chuàng)作

致力于為大家講解清晰Java相關(guān)知識(shí)點(diǎn),含有豐富的代碼案例及講解。如果感覺對大家有幫助的話,可以【點(diǎn)個(gè)關(guān)注】持續(xù)追更~

有技術(shù)類問題,也歡迎大家和我們交流討論!

前言

在上一篇文章中本系列內(nèi)容給大家講解了Java里的格式化問題,這樣我們就可以個(gè)性化設(shè)置日期時(shí)間的展示方式了。似乎我們現(xiàn)在已經(jīng)掌握了不少關(guān)于日期和時(shí)間的操作技巧,但其實(shí)隨著時(shí)間的不斷推移,現(xiàn)實(shí)的需求也在不斷更新,原先的一些API已經(jīng)難以滿足開發(fā)需求了。所以從JDK 8之后,為了滿足更多的開發(fā)需求,Java給我們增加了不少關(guān)于日期時(shí)間的新特性,接下來本篇文章就帶各位來看看這些新特性有哪些。


全文大約 【5400】字, 不說廢話,只講可以讓你學(xué)到技術(shù)、明白原理的純干貨!本文帶有豐富的案例及配圖,讓你更好地理解和運(yùn)用文中的技術(shù)概念,并可以給你帶來具有足夠啟迪的思考…

一. 新特性概述

在JDK 8之前,其實(shí)有不少的API都存在著一些問題,日期時(shí)間等相關(guān)類同樣如此。所以從JDK 8開始,Java做了較大的改動(dòng),出現(xiàn)了很多新特性。其中,java.time包中了就提供了不少新的日期和時(shí)間API,主要如下:

● 本地日期和時(shí)間類:LocalDateTime,LocalDate,LocalTime;

● 帶時(shí)區(qū)的日期和時(shí)間類:ZonedDateTime;

● 時(shí)刻類:Instant;

● 時(shí)區(qū):ZoneId,ZoneOffset;

● 時(shí)間間隔:Duration。

在格式化操作方面,也推出了一個(gè)新的格式化類DateTimeFormatter。

和之前那些舊的API相比,新的時(shí)間API嚴(yán)格區(qū)分了時(shí)刻、本地日期、本地時(shí)間和帶時(shí)區(qū)的日期時(shí)間,日期和時(shí)間的運(yùn)算更加方便。這些新的API類型幾乎全都是final不變類型,我們不必?fù)?dān)心其會(huì)被修改。并且新的API還修正了舊API中一些不合理的常量設(shè)計(jì):

● Month的范圍采用1~12,分別表示1月到12月;

● Week的范圍采用1~7,分別表示周一到周日。

二. LocalDateTime

1. 簡介

LocalDateTime是JDK 8之后出現(xiàn)的,用來表示本地日期和時(shí)間的類。我們可以通過now()方法,默認(rèn)獲取到本地時(shí)區(qū)的日期和時(shí)間。與之前的舊API不同,LocalDateTime、LocalDate和LocalTime默認(rèn)會(huì)嚴(yán)格按照ISO 8601規(guī)定的日期和時(shí)間格式進(jìn)行打印。

2. 獲取當(dāng)前日期和時(shí)間

我們可以通過now()方法來獲取到當(dāng)前的日期和時(shí)間。我們在執(zhí)行一行代碼時(shí),多少也會(huì)消耗一點(diǎn)時(shí)間,日期和時(shí)間的值可能會(huì)對不上,尤其是時(shí)間的毫秒數(shù)可能會(huì)有差異。所以為了保證獲取到的日期和時(shí)間值差異減少,我們的代碼盡量要編寫如下:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Demo10 {

	public static void main(String[] args) {
		//獲取當(dāng)前日期和時(shí)間
		LocalDateTime dt = LocalDateTime.now();
		System.out.println("dt="+dt);
		
		// 轉(zhuǎn)換到當(dāng)前日期
		LocalDate d = dt.toLocalDate(); 
		System.out.println("date="+d);
		
		// 轉(zhuǎn)換到當(dāng)前時(shí)間
		LocalTime t = dt.toLocalTime(); 
		System.out.println("time="+t);
	}

}

3. of()方法的作用

我們可以通過of()方法,根據(jù)指定的日期和時(shí)間來創(chuàng)建一個(gè)LocalDateTime對象,用法如下:
【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性

4. parse()方法的作用

我們可以使用parse()方法,將一個(gè)時(shí)間格式的字符串解析為LocalDateTime,用法如下:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Demo11 {

	public static void main(String[] args) {
		// 解析時(shí)間字符串。T是日期和時(shí)間的分隔符
		LocalDateTime dt = LocalDateTime.parse("2023-02-22T20:18:15");
		System.out.println("dt="+dt);
		
		LocalDate date = LocalDate.parse("2012-10-15");
		System.out.println("date="+date);
		
		LocalTime time = LocalTime.parse("16:15:20");
		System.out.println("time="+time);
	}
}

我們要注意,根據(jù)ISO 8601規(guī)定,日期和時(shí)間的分隔符是T,標(biāo)準(zhǔn)格式如下:

● 日期:yyyy-MM-dd

● 時(shí)間:HH:mm:ss

● 帶毫秒的時(shí)間:HH:mm:ss.SSS

● 日期和時(shí)間:yyyy-MM-dd’T’HH:mm:ss

● 帶毫秒的日期和時(shí)間:yyyy-MM-dd’T’HH:mm:ss.SSS

5. 時(shí)間加減方法

LocalDateTime中,給我們提供了一系列的加減操作方法,使得我們可以很輕易的實(shí)現(xiàn)時(shí)間的加減操作,比如給某個(gè)日期或時(shí)間進(jìn)行加或減的操作。plusXxx()增加方法如下圖所示:

【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性

minusXxx()減少方法如下圖所示:

【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性

import java.time.LocalDateTime;

public class Demo13 {

	public static void main(String[] args) {
		// 對日期進(jìn)行加減操作
		LocalDateTime dt1 = LocalDateTime.now();
		System.out.println("dt1=" + dt1);
		
        // 加3天減6小時(shí):
        LocalDateTime dt2 = dt1.plusDays(3).minusHours(6);
        // 2019-10-31T17:30:59
        System.out.println("dt2=" +dt2); 
        
        // 減1月:
        LocalDateTime dt3 = dt2.minusMonths(1);
        // 2019-09-30T17:30:59
        System.out.println("dt3=" +dt3); 
        
        //加兩周
        LocalDateTime dt4 = dt3.plusWeeks(2);
        System.out.println("dt4=" +dt4); 
	}

}

6. 時(shí)間調(diào)整方法

我們除了可以進(jìn)行日期和時(shí)間的增加、減少操作之外,還可以利用withXxx()方法對日期和時(shí)間進(jìn)行調(diào)整,這些方法如下圖所示:

【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性

從上圖可以看出,我們可以對年、月、日、時(shí)、分、秒等進(jìn)行調(diào)整,具體含義如下:

● 調(diào)整年:withYear()

● 調(diào)整月:withMonth()

● 調(diào)整日:withDayOfMonth()

● 調(diào)整時(shí):withHour()

● 調(diào)整分:withMinute()

● 調(diào)整秒:withSecond()

import java.time.LocalDateTime;

public class Demo14 {

	public static void main(String[] args) {
		// 對日期進(jìn)行加減操作
		LocalDateTime dt1 = LocalDateTime.now();
		System.out.println("dt1=" + dt1);
		
		// 注意:如果某個(gè)月中沒有29、30、31等日期,會(huì)出現(xiàn)java.time.DateTimeException: Invalid date 'FEBRUARY 31'類似的異常。
        //LocalDateTime dt2 = dt1.withDayOfMonth(31);
		
		//日期變?yōu)?5日
        LocalDateTime dt2 = dt1.withDayOfMonth(25);
        System.out.println("dt2="+dt2); // 2019-10-31T20:30:59
        
        //月份變成5月
        LocalDateTime dt3 = dt2.withMonth(5);
        //2023-05-25T20:06:06.768
        System.out.println("dt3="+dt3); 
		
        //年份變成2024年
        LocalDateTime dt4 = dt3.withYear(2024);
        //2024-05-25T20:06:06.768
        System.out.println("dt4=" +dt4); 
	}

}

我們在利用withXxx()方法調(diào)整時(shí)間是,在調(diào)整月份時(shí),會(huì)相應(yīng)地調(diào)整日期。并且要注意,如果某個(gè)月中沒有29、30、31等日期,會(huì)出現(xiàn)java.time.DateTimeException: Invalid date 'FEBRUARY 31'類似的異常,如下圖:

【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性

7. with()方法

LocalDateTime中有一個(gè)通用的with()方法,允許我們進(jìn)行更復(fù)雜的運(yùn)算,比如獲取當(dāng)月或下個(gè)月的第一天、最后一天、第一個(gè)周一等操作。

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;

public class Demo14 {

	public static void main(String[] args) {
        //獲取本月的第一天0:00時(shí)刻:
        LocalDateTime firstDay = LocalDate.now().withDayOfMonth(1).atStartOfDay();
        System.out.println("firstDay="+firstDay);

        //獲取本月的最后1天:
        LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        System.out.println("lastDay="+lastDay);

        //獲取下個(gè)月的第1天:
        LocalDate nextMonthFirstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth());
        System.out.println("nextMonthFirstDay="+nextMonthFirstDay);

        //獲取本月的第1個(gè)周一
        LocalDate firstWeekday = LocalDate.now().with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
        System.out.println("firstWeekday="+firstWeekday);
	}

}

8. isBefore()與isAfter()方法

如果我們判斷兩個(gè)LocalDateTime的先后順序,可以使用isBefore()、isAfter()方法。

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class Demo16 {

	public static void main(String[] args) {
		LocalDateTime now = LocalDateTime.now();
        LocalDateTime target = LocalDateTime.of(2022, 12, 25, 10, 15, 10);
        //判斷A日期在B日期之前
        System.out.println("before?="+now.isBefore(target));
        
        //判斷A日期在B日期之前
        System.out.println(LocalDate.now().isBefore(LocalDate.of(2023, 12, 19)));
        
        //判斷A時(shí)間在B時(shí)間之后
        System.out.println(LocalTime.now().isAfter(LocalTime.parse("10:15:20")));
	}

}

9. Duration時(shí)間間隔和Period間隔天數(shù)

我們可以使用Duration表示兩個(gè)時(shí)刻之間的時(shí)間間隔,用Period表示兩個(gè)日期之間的間隔天數(shù)。

DurationPeriod的表示方法也符合ISO 8601的格式,它以P…T…的形式表示。P…T之間表示日期間隔,T后面表示時(shí)間間隔,如果是PT…的格式表示僅有時(shí)間間隔。

所以如果是兩個(gè)LocalDateTime之間的差值,要使用Duration表示,形式為PT12H10M30S,意思是間隔12小時(shí)10分鐘30秒。而兩個(gè)LocalDate之間的差值用Period表示,形式為P1M21D,表示間隔1個(gè)月21天。

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;

public class Demo17 {

	public static void main(String[] args) {
		LocalDateTime start = LocalDateTime.of(2023, 05, 24, 13, 15, 20);
        LocalDateTime end = LocalDateTime.of(2025, 11, 8, 19, 25, 30);
        //計(jì)算兩個(gè)時(shí)間的間隔
        Duration d = Duration.between(start, end);
        //PT21582H10M10S,間隔21582小時(shí)10分10秒
        System.out.println("duration="+d); 

        //計(jì)算兩個(gè)日期的間隔
        Period p = LocalDate.of(2022, 12, 11).until(LocalDate.of(2025, 2, 22));
        //P2Y2M11D,間隔2個(gè)月11天
        System.out.println("period="+p); 
        
        //我們也可以使用ofXxx()或parse()方法直接創(chuàng)建Duration
        //10hours
        Duration d1 = Duration.ofHours(10);
        //2day,4hours,5minutes
        Duration d2 = Duration.parse("P2DT4H5M"); 
        System.out.println("d1="+d1); 
        System.out.println("d2="+d2); 
	}

}

三. ZonedDateTime

1. 簡介

我們知道,LocalDateTime表示本地日期和時(shí)間,如果我們要表示一個(gè)帶時(shí)區(qū)的日期和時(shí)間,就需要使用ZonedDateTime了。ZonedDateTime相當(dāng)于是LocalDateTime + ZoneId,其中ZoneId是java.time引入的新的時(shí)區(qū)類,它與舊的java.util.TimeZone是有區(qū)別的。在ZonedDateTime中也提供了plusDays()等加減操作,使用起來也非常地方便。

2. 創(chuàng)建方式

如果我們想要?jiǎng)?chuàng)建一個(gè)ZonedDateTime對象,可以有以下幾種方法:

● 通過now()方法返回ZonedDateTime對象;

● 通過給LocalDateTime附加ZoneId獲取。

接下來我們就通過一些具體的案例來給大家展示一下ZonedDateTime到底是怎么創(chuàng)建的

2.1 now()方法

我們先來看看通過now()方法如何創(chuàng)建一個(gè)ZonedDateTime對象。

import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Demo18 {

	public static void main(String[] args) {
		//獲取默認(rèn)時(shí)區(qū)的時(shí)間對象
		ZonedDateTime zdt1 = ZonedDateTime.now(); 
		System.out.println("zdt1="+zdt1); 
		
		 //獲取指定時(shí)區(qū)的時(shí)間對象
        ZonedDateTime zdt2 = ZonedDateTime.now(ZoneId.of("America/New_York"));
        System.out.println("zdt2="+zdt2); 
	}

}

在這個(gè)案例中,我們獲得的兩個(gè)ZonedDateTime對象,它們的時(shí)區(qū)雖然不同,但時(shí)間都是同一時(shí)刻的,如果毫秒數(shù)不同是在執(zhí)行語句時(shí)有一點(diǎn)時(shí)間差。

2.2 附加ZoneId

我們再來通過給LocalDateTime附加ZoneId的方式來獲取一個(gè)LocalDateTime對象。

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Demo19 {

	public static void main(String[] args) {
		LocalDateTime ldt = LocalDateTime.of(2023, 1, 25, 10, 15, 11);
		//獲取默認(rèn)時(shí)區(qū)的時(shí)間對象
		ZonedDateTime zdt1 = ldt.atZone(ZoneId.systemDefault());
		System.out.println("zdt1=" + zdt1);

		//獲取指定時(shí)區(qū)的時(shí)間對象
		ZonedDateTime zdt2 = ldt.atZone(ZoneId.of("America/New_York"));
		System.out.println("zdt2=" + zdt2);
	}

}

這種方式創(chuàng)建的ZonedDateTime對象,其日期和時(shí)間與LocalDateTime相同,但附加的時(shí)區(qū)不同,因此是兩個(gè)不同的時(shí)刻。

3. 時(shí)區(qū)轉(zhuǎn)換

有時(shí)候我們的項(xiàng)目中,需要將A時(shí)區(qū)的時(shí)間轉(zhuǎn)換成B時(shí)區(qū)的時(shí)間,要在兩個(gè)時(shí)區(qū)直接進(jìn)行切換。以前的時(shí)候就需要我們自己計(jì)算,非得的麻煩且復(fù)雜,現(xiàn)在新的Java API中直接給我們帶了負(fù)責(zé)時(shí)區(qū)轉(zhuǎn)換的方法。比如withZoneSameInstant()方法,就可以將一個(gè)關(guān)聯(lián)的時(shí)區(qū)轉(zhuǎn)換到另一個(gè)時(shí)區(qū),轉(zhuǎn)換后的日期和時(shí)間也會(huì)相應(yīng)調(diào)整。

import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Demo20 {
	public static void main(String[] args) {
		//將北京時(shí)間轉(zhuǎn)為紐約時(shí)間
		//獲取北京時(shí)區(qū)的當(dāng)前時(shí)間
		//注意:這里的時(shí)區(qū)名字不能隨便瞎寫,否則會(huì)產(chǎn)生java.time.zone.ZoneRulesException: Unknown time-zone ID: Asia/Beijing
        ZonedDateTime zdt1 = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        System.out.println("zdt1=" + zdt1);
        
        //將當(dāng)前時(shí)區(qū)的時(shí)間,轉(zhuǎn)換為紐約時(shí)間
        ZonedDateTime zdt2 = zdt1.withZoneSameInstant(ZoneId.of("America/New_York"));
		System.out.println("zdt2=" + zdt2);

        //轉(zhuǎn)換為本地時(shí)間
		LocalDateTime ldt = zdt2.toLocalDateTime();
		System.out.println("ldt=" + ldt);
	}
}

注意:

時(shí)區(qū)的名字不能隨便瞎寫,否則會(huì)產(chǎn)生java.time.zone.ZoneRulesException: Unknown time-zone ID: Asia/Beijing,如下圖所示:

【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性

而且在時(shí)區(qū)轉(zhuǎn)換時(shí),由于夏令時(shí)的存在,不同的日期轉(zhuǎn)換結(jié)果也有可能是不同的,有可能會(huì)出現(xiàn)兩次轉(zhuǎn)換后有1小時(shí)的夏令時(shí)時(shí)差。我們以后涉及到時(shí)區(qū)時(shí),盡量不要自己計(jì)算時(shí)差,否則難以正確處理夏令時(shí)。

四. DateTimeFormatter

1. 簡介

我們在前面學(xué)習(xí)Date日期時(shí)間對象時(shí),知道該對象默認(rèn)輸出的時(shí)間格式其實(shí)是不符合大多數(shù)的使用場景的,所以就需要我們對其進(jìn)行格式化設(shè)置,比如通過printf()方法或SimpleDateFormat類來實(shí)現(xiàn)。但是當(dāng)我們使用新的LocalDateTimeZonedDateTime需要進(jìn)行格式化顯示時(shí),就要使用新的DateTimeFormatter類了。

SimpleDateFormat不同的是,DateTimeFormatter不但是不可變的對象,且還是線程安全的。在代碼中,我們可以創(chuàng)建出一個(gè)DateTimeFormatter實(shí)例對象,到處引用。而之前的SimpleDateFormat是線程不安全的,使用時(shí)只能在方法內(nèi)部創(chuàng)建出一個(gè)新的局部變量。

2. 創(chuàng)建方式

我們要想使用DateTimeFormatter,首先得創(chuàng)建出一個(gè)DateTimeFormatter對象,一般有如下兩種方式:

● DateTimeFormatter.ofPattern(String pattern):pattern是待傳入的格式化字符串;

● DateTimeFormatter.ofPattern(String pattern,Locale locale):locale是所采用的本地化設(shè)置。

3. 基本使用

了解了創(chuàng)建方式之后,我們就可以來看看該如何進(jìn)行時(shí)間格式化了。

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Demo21 {

	public static void main(String[] args) {
		//獲取默認(rèn)的本地時(shí)間
		ZonedDateTime zdt = ZonedDateTime.now();
		//獲取一個(gè)DateTimeFormatter對象,如果需要輸出固定字符,可以用'xxx'表示,如'中國時(shí)間'
        var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss ZZZZ '中國時(shí)間'");
        System.out.println(formatter.format(zdt));

        //獲取一個(gè)DateTimeFormatter對象,中國時(shí)區(qū)
        var zhFormatter = DateTimeFormatter.ofPattern("yyyy MMM dd EE HH:mm:ss", Locale.CHINA);
        System.out.println(zhFormatter.format(zdt));
        //改變默認(rèn)的顯示格式,用指定的格式顯示
        //System.out.println(DateTimeFormatter.ISO_DATE.format(zdt));

        //獲取一個(gè)DateTimeFormatter對象,美國時(shí)區(qū)
        var usFormatter = DateTimeFormatter.ofPattern("E, MMMM/dd/yyyy HH:mm:ss", Locale.US);
        //System.out.println(usFormatter.format(zdt));
        //改變默認(rèn)的顯示格式
        System.out.println(DateTimeFormatter.ISO_DATE_TIME.format(zdt));
	}

}

當(dāng)我們在格式化字符串時(shí),如果需要輸出一些固定的字符,可以用’xxx’的形式來表示。

另外我們在調(diào)用System.out.println()方法對一個(gè)ZonedDateTime,或者LocalDateTime實(shí)例進(jìn)行打印時(shí),實(shí)際上調(diào)用的是它們的toString()方法。默認(rèn)的toString()方法,顯示的字符串是按照ISO 8601格式顯示的,我們可以通過DateTimeFormatter預(yù)定義的幾個(gè)靜態(tài)變量來引用。

五. Instant

1. 簡介

在之前給大家講過,計(jì)算機(jī)中存儲(chǔ)的當(dāng)前時(shí)間,其實(shí)就是一個(gè)不斷遞增的整數(shù),即從1970年1月1日0分0秒開始以來不斷遞增的一個(gè)整數(shù)值。要想獲取這個(gè)整數(shù)值,我們可以使用System.currentTimeMillis()方法,該方法會(huì)返回一個(gè)long型的毫秒值,這就是當(dāng)前時(shí)間的時(shí)間戳!

現(xiàn)在,我們其實(shí)還可以使用Instant.now()來獲取當(dāng)前的時(shí)間戳,效果和System.currentTimeMillis()類似。但I(xiàn)nstant獲取的時(shí)間戳更為精確,內(nèi)部采用了兩種時(shí)間精度,分別是秒和納秒。

另外Instant還提供了plusXxxminusXxx增減方法,方便我們進(jìn)行時(shí)間的操作。且Instant作為時(shí)間戳對象,我們還可以給它附加上一個(gè)時(shí)區(qū),創(chuàng)建出對應(yīng)的ZonedDateTime對象。也可以給它關(guān)聯(lián)上指定的ZoneId,得到對應(yīng)的ZonedDateTime,進(jìn)而獲得對應(yīng)時(shí)區(qū)的LocalDateTime。所以我們可以在LocalDateTime、ZoneId、Instant、ZonedDateTime之間互相轉(zhuǎn)換。

2. 使用方法

接下來我們看看Instant的用法。

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Demo22 {

	public static void main(String[] args) {
		//獲取當(dāng)前時(shí)間的時(shí)間戳
		long currentTimeMillis = System.currentTimeMillis();
		System.out.println("currentTimeMillis毫秒級時(shí)間戳="+currentTimeMillis);

		//獲取當(dāng)前時(shí)間的時(shí)間戳
		Instant now = Instant.now();
		System.out.println("now時(shí)刻="+now);
		// 秒
        System.out.println("秒級時(shí)間戳="+now.getEpochSecond()); 
        // 毫秒
        System.out.println("毫秒級時(shí)間戳="+now.toEpochMilli());
		
		//用指定的時(shí)間戳創(chuàng)建Instant對象
		Instant ins = Instant.ofEpochSecond(1676262418);
		//獲取所在時(shí)區(qū)的ZonedDateTime對象
		ZonedDateTime zdt = ins.atZone(ZoneId.systemDefault());
		System.out.println("zdt="+zdt); 
	}

}

六. 新舊時(shí)間API的轉(zhuǎn)換

1. 簡介

。
現(xiàn)在我們知道,在Java中,關(guān)于日期和時(shí)間的API其實(shí)有兩套,一套舊的,一套新的。這兩套API以JDK 8為分割線,此前的屬于舊版API,此后的屬于新版API

● 舊版API:定義在java.util包中,主要包括Date、Calendar和TimeZone幾個(gè)類;

● 新版API:JDK 8之后引入,定義在java.time包中,主要包括LocalDateTime、ZonedDateTime、ZoneId、DateTimeFormatter、Instant等。

這時(shí)有些同學(xué)就會(huì)好奇,這兩套時(shí)間API我們在開發(fā)時(shí)該怎么選擇?

1、如果大家的項(xiàng)目屬于是一個(gè)新開發(fā)的項(xiàng)目,且你們的Java版本在JDK 8以上,那就采用新版的API吧。

2、但是如果你們的項(xiàng)目涉及到遺留代碼,是對舊的項(xiàng)目進(jìn)行維護(hù)或改造,很多遺留代碼仍然在使用舊的API,建議大家還是不要改變原有的選擇,請繼續(xù)使用舊版API。

3、但是如果你們的項(xiàng)目環(huán)境已經(jīng)從低版本的JDK切換到了高本版的JDK,且你們公司要求對項(xiàng)目進(jìn)行升級改造,我們能不能在新舊兩種API之間進(jìn)行轉(zhuǎn)換呢? 其實(shí)也是可以的,今天就給大家講一下如何在新舊兩套API之間互相轉(zhuǎn)換。

2. 舊轉(zhuǎn)新

首先我們來看看舊的API是如何轉(zhuǎn)成新的API的。比如我們想把舊式的Date或Calendar轉(zhuǎn)換為新的API對象,可以通過toInstant()方法轉(zhuǎn)換為Instant對象,然后再繼續(xù)轉(zhuǎn)換為ZonedDateTime,實(shí)現(xiàn)代碼如下:

import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;

public class Demo24 {

	public static void main(String[] args) {
		//將舊版API中的Date,轉(zhuǎn)為新版API中的Instant對象
		Instant instant = new Date().toInstant();
		System.out.println("instant="+instant);
		
		//將舊版API中的Calendar,轉(zhuǎn)為新版API中的Instant,然后再進(jìn)一步轉(zhuǎn)為新版的ZonedDateTime:
		Calendar calendar = Calendar.getInstance();
		Instant instant2 = calendar.toInstant();
		ZonedDateTime zdt = instant2.atZone(calendar.getTimeZone().toZoneId());
		System.out.println("zdt="+zdt); 
	}

}

3. 新轉(zhuǎn)舊

舊版API可以轉(zhuǎn)換成新版API,同時(shí)我們也可以將新班API轉(zhuǎn)成舊版的API,已實(shí)現(xiàn)與原有系統(tǒng)的兼容。如果要實(shí)現(xiàn)這一目標(biāo),我們需要借助long型的時(shí)間戳做一個(gè)“中轉(zhuǎn)”,具體實(shí)現(xiàn)如下:

import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class Demo25 {

	public static void main(String[] args) {
		//新版API中的ZonedDateTime,先轉(zhuǎn)為long類型
		ZonedDateTime zdt = ZonedDateTime.now();
		//獲取秒級時(shí)間戳,轉(zhuǎn)為long類型
		long ts = zdt.toEpochSecond() * 1000;
		System.out.println("ts=" + ts);

		//然后將long類型,轉(zhuǎn)為舊版API中的Date
		Date date = new Date(ts);
		System.out.println("date=" + date);
		
		//將long類型轉(zhuǎn)為舊版API中的Calendar對象
		Calendar calendar = Calendar.getInstance();
		calendar.clear();
		calendar.setTimeZone(TimeZone.getTimeZone(zdt.getZone().getId()));
		calendar.setTimeInMillis(zdt.toEpochSecond() * 1000);
		System.out.println("calendar=" + calendar);
	}

}

七. 結(jié)語

至此,就把日期的格式化操作給大家講解完畢了,今天的內(nèi)容比較多且很實(shí)用,最后我們總結(jié)一下今日重點(diǎn)

● JDK 8中引入了新的日期和時(shí)間API,它們是不變類,默認(rèn)按ISO 8601標(biāo)準(zhǔn)格式化和解析;

● 使用LocalDateTime可以非常方便地對日期和時(shí)間進(jìn)行加減、調(diào)整日期和時(shí)間,且總是返回新對象;

● 使用isBefore()和isAfter()可以判斷日期和時(shí)間的先后;

● 使用Duration和Period可以表示兩個(gè)日期和時(shí)間的“區(qū)間間隔”;

● ZonedDateTime是帶時(shí)區(qū)的日期和時(shí)間,可用于時(shí)區(qū)轉(zhuǎn)換;

● ZonedDateTime和LocalDateTime可以相互轉(zhuǎn)換;

● 對ZonedDateTime或LocalDateTime進(jìn)行格式化,需要使用DateTimeFormatter類;

● DateTimeFormatter可以通過格式化字符串和Locale對日期和時(shí)間進(jìn)行定制輸出;

● Instant表示高精度時(shí)間戳,它可以和ZonedDateTime以及l(fā)ong互相轉(zhuǎn)換;

● 處理日期和時(shí)間時(shí),盡量使用新的java.time包;

● 新舊兩種API之間可以進(jìn)行轉(zhuǎn)換,舊版轉(zhuǎn)新版可以通過toInstant()方法轉(zhuǎn)換為Instant對象,然后再繼續(xù)轉(zhuǎn)換為ZonedDateTime;新版轉(zhuǎn)舊版需要借助long型的時(shí)間戳做一個(gè)“中轉(zhuǎn)”。


以上就是我們本篇內(nèi)容的詳細(xì)講解了~ 大家學(xué)會(huì)了嗎

有技術(shù)類問題歡迎大家和我們一起交流討論,更多技術(shù)類干貨,關(guān)注千鋒教育技術(shù)團(tuán)文章來源地址http://www.zghlxwxcb.cn/news/detail-469738.html

到了這里,關(guān)于【從零開始學(xué)Java第64期】JDK8 關(guān)于日期時(shí)間的新特性的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • JDK8-JDK17中的新特性(var類型推斷、模式匹配、Record、密封類)

    JDK8-JDK17中的新特性(var類型推斷、模式匹配、Record、密封類)

    新的語法結(jié)構(gòu),勾勒出了 Java 語法進(jìn)化的一個(gè)趨勢,將開發(fā)者從 復(fù)雜、繁瑣 的低層次抽象中逐漸解放出來,以更高層次、更優(yōu)雅的抽象,既 降低代碼量 ,又避免意外編程錯(cuò)誤的出現(xiàn),進(jìn)而提高代碼質(zhì)量和開發(fā)效率。 1.1 Java的REPL工具: jShell命令 JDK9的新特性 Java 終于擁有了

    2024年02月06日
    瀏覽(26)
  • Java常用類之 JDK 8之前的日期時(shí)間API 和 8中新日期時(shí)間API

    Java常用類 JDK 8 之前日期和時(shí)間的API測試: 詳細(xì)代碼如下: SimpleDateFormate的使用: SimpleDateFormate對日期Date類的格式化和解析 重點(diǎn)關(guān)注: 具體代碼如下: 1.獲取Calendar實(shí)例的方法 2.重點(diǎn)掌握幾個(gè)常用方法: 注意: 獲取月份時(shí):一月是0,二月是1,以此類推,12月是11 獲取星期

    2024年02月07日
    瀏覽(24)
  • Nacos啟動(dòng)報(bào)錯(cuò):Please set the JAVA_HOME variable in your environment, We need java(x64) jdk8 or later is

    Nacos啟動(dòng)報(bào)錯(cuò):Please set the JAVA_HOME variable in your environment, We need java(x64) jdk8 or later is

    錯(cuò)誤:Please set the JAVA_HOME variable in your environment, We need java(x64)!?jdk8?or later is better! 請?jiān)谀沫h(huán)境中設(shè)置JAVA HOME變量,我們需要JAVA(x64)JDK8或更高版本 解決方案:網(wǎng)上找的的解決方案,試過可行,為防止以后找不到,特總結(jié)于此,另外最下面會(huì)附上參考博客地址。 檢查JDK版

    2024年02月16日
    瀏覽(16)
  • JDK8新時(shí)間類(二)

    格式化器,用于時(shí)間的格式化、解析 方法名 說明 public?static?DateTimeFormatter?ofPattern(時(shí)間格式) 獲取格式化器對象 public?String?format(時(shí)間對象) 格式化時(shí)間 LocalDateTime提供的格式化、解析時(shí)間的方法 方法名|說明 public?String?format(DateTimeFormatter?formatter)|格式化時(shí)間 public?

    2024年02月22日
    瀏覽(12)
  • 關(guān)于JDK8的安裝和卸載

    關(guān)于JDK8的安裝和卸載

    我的電腦—屬性—高級系統(tǒng)設(shè)置—環(huán)境變量 在系統(tǒng)變量中找到 JAVA_HOME ,查看所在的地址,在計(jì)算機(jī)中找到并將整個(gè)文件夾刪了,里面就包含jdk文件夾。 在系統(tǒng)變量中找到path,刪除關(guān)于JAVA_HOME的內(nèi)容。 classpath中也找到關(guān)于JAVA_HOME的內(nèi)容刪除。這樣JDK就刪干凈了。 最后測試一

    2024年02月11日
    瀏覽(15)
  • 從零開始學(xué)習(xí) Java:簡單易懂的入門指南之時(shí)間類(十七)

    java.util.Date`類 表示特定的瞬間,精確到毫秒。 繼續(xù)查閱Date類的描述,發(fā)現(xiàn)Date擁有多個(gè)構(gòu)造函數(shù),只是部分已經(jīng)過時(shí),我們重點(diǎn)看以下兩個(gè)構(gòu)造函數(shù) public Date() :從運(yùn)行程序的此時(shí)此刻到時(shí)間原點(diǎn)經(jīng)歷的毫秒值,轉(zhuǎn)換成Date對象,分配Date對象并初始化此對象,以表示分配它的時(shí)

    2024年02月11日
    瀏覽(1071)
  • 關(guān)于老項(xiàng)目從JDK8升級到JDK17所需要注意的細(xì)節(jié)

    關(guān)于老項(xiàng)目從JDK8升級到JDK17所需要注意的細(xì)節(jié)

    這個(gè)是最簡單的網(wǎng)上很多教程我這邊就不在重復(fù)了 ??1.第一種方式 ??1.1.修改Idea中的JDK版本 跟步驟修改 修改Java Compiler ??1.2.關(guān)于修改過程中遇到的異常 如果出現(xiàn)下面異常按照上述步驟定可以解決 ??1.3.IDEA工具欄操作Maven正常,但使用mvn命令運(yùn)行就報(bào)錯(cuò) 使用側(cè)工具欄的打包

    2024年02月07日
    瀏覽(42)
  • API(Date類,SimpleDateFormat類,Calendar類,JDK8時(shí)間相關(guān)類,包裝類,算法小題)

    API(Date類,SimpleDateFormat類,Calendar類,JDK8時(shí)間相關(guān)類,包裝類,算法小題)

    JDK7時(shí)間相關(guān)類 JDK8時(shí)間相關(guān)類 包裝類 綜合練習(xí) Collection集合 能夠使用日期類輸出當(dāng)前日期 能夠使用將日期格式化為字符串的方法 能夠使用將字符串轉(zhuǎn)換成日期的方法 能夠說出8種基本類型對應(yīng)的包裝類名稱 能夠說出自動(dòng)裝箱、自動(dòng)拆箱的概念 能夠?qū)⒆址D(zhuǎn)換為對應(yīng)的基

    2024年02月02日
    瀏覽(17)
  • Unity + HybridCLR,近乎完美的新熱更方案,從零開始(一)——Hello World

    Unity + HybridCLR,近乎完美的新熱更方案,從零開始(一)——Hello World

    最近又新接觸了一種unity熱更的解決方案——HybridCLR,自稱是: 特性完整、零成本、高性能、低內(nèi)存的近乎完美的Unity全平臺(tái)原生c#熱更方案 。 接下來我們就來一起學(xué)習(xí)下。 下面是官方文檔的鏈接,一切以官方為主:HybridCLR HybridCLR擴(kuò)充了il2cpp的代碼,使它由純AOT runtime變成

    2024年02月07日
    瀏覽(18)
  • java jdk8和jdk17同時(shí)存在【環(huán)境配置】

    java jdk8和jdk17同時(shí)存在【環(huán)境配置】

    jdk8:https://www.oracle.com/cn/java/technologies/javase/javase8u211-later-archive-downloads.html jdk17:https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html PS:jdk8在下載結(jié)束,安裝的時(shí)候,需要有兩個(gè)文件分別是jre和jdk JRE: 是Java Runtime Environment,是java程序的運(yùn)行環(huán)境。既然是運(yùn)行,當(dāng)然要包含

    2024年02月07日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包