1. 程式人生 > >Java8之日期和時間(四)

Java8之日期和時間(四)

Java 8新增了LocalDateLocalTime介面,為什麼要搞一套全新的處理日期和時間的API。因為舊的java.util.Date實在是太難用了。

java.util.Date月份從0開始,一月是0,十二月是11,變態吧!java.time.LocalDate月份和星期都改成了enum,就不可能再用錯了。

java.util.DateSimpleDateFormatter都不是執行緒安全的,而LocalDateLocalTime和最基本的String一樣,是不變型別,不但執行緒安全,而且不能修改。

java.util.Date是一個“萬能介面”,它包含日期、時間,還有毫秒數,如果你只想用java.util.Date

儲存日期,或者只儲存時間,那麼,只有你知道哪些部分的資料是有用的,哪些部分的資料是不能用的。在新的Java 8中,日期和時間被明確劃分為LocalDateLocalTimeLocalDate無法包含時間,LocalTime無法包含日期。當然,LocalDateTime才能同時包含日期和時間。

新介面更好用的原因是考慮到了日期時間的操作,經常發生往前推或往後推幾天的情況。用java.util.Date配合Calendar要寫好多程式碼,而且一般的開發人員還不一定能寫對。

LocalDateLocalTimeLocalDateTime 類的例項是別表示使用ISO-8601日曆系統的日期、時間、日期和時間。它們提供了簡單的日期或時間,並不包含當前的時間資訊。也不包含與時區相關的資訊。

1. LocalDate

看看新的LocalDate怎麼用:

// 取當前日期:
LocalDate today = LocalDate.now(); // -> 2014-12-24
// 根據年月日取日期,12月就是12:
LocalDate crischristmas = LocalDate.of(2014, 12, 25); // -> 2014-12-25
// 根據字串取:
LocalDate endOfFeb = LocalDate.parse("2014-02-28"); // 嚴格按照ISO yyyy-MM-dd驗證,02寫成2都不行,當然也有一個過載方法允許自己定義格式
LocalDate.parse("2014-02-29"
); // 無效日期無法通過:DateTimeParseException: Invalid date

日期轉換經常遇到,比如:

// 取本月第1天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 2014-12-01
// 取本月第2天:
LocalDate secondDayOfThisMonth = today.withDayOfMonth(2); // 2014-12-02
// 取本月最後一天,再也不用計算是28,29,30還是31:
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); // 2014-12-31
// 取下一天:
LocalDate firstDayOf2015 = lastDayOfThisMonth.plusDays(1); // 變成了2015-01-01
// 取2015年1月第一個週一,這個計算用Calendar要死掉很多腦細胞:
LocalDate firstMondayOf2015 = LocalDate.parse("2015-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); // 2015-01-05

2. LocalTime

LocalTime只包含時間,以前用java.util.Date怎麼才能只表示時間呢?答案是,假裝忽略日期。

LocalTime包含毫秒:

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

時間也是按照ISO格式識別,但可以識別以下3種格式:

  • 12:00
  • 12:01:02
  • 12:01:02.345

JDBC

最新JDBC對映將把資料庫的日期型別和Java 8的新型別關聯起來:

SQL -> Java
--------------------------
date -> LocalDate
time -> LocalTime
timestamp -> LocalDateTime

再也不會出現對映到java.util.Date其中日期或時間某些部分為0的情況了。

3.LocalDateTime

LocalDateTime類是Java 8中日期時間功能裡,用於表示當地的日期與時間的類,它的值是無時區屬性的。你可以將其視為Java 8中LocalDate與LocalTime兩個類的結合。LocalDateTime類的值是不可變的,所以其計算方法會返回一個新的LocalDateTime例項。

建立一個LocatDateTime例項
可以通過LocalDateTime的靜態工廠方法來建立LocalDateTime例項。以下舉例使用now()方法建立:
LocalDateTime localDateTime = LocalDateTime.now();
另一種方式是使用指定的年月日、時分秒、納秒來新建物件:
LocalDateTime localDateTime2 = LocalDateTime.of(2015, 11, 26, 13, 55, 36, 123);


示例:

@Test
public void test1(){
		LocalDateTime ldt = LocalDateTime.now();
		System.out.println(ldt);
		LocalDateTime ld2 = LocalDateTime.of(2016, 11, 21, 10, 10, 10);
		System.out.println(ld2);
		LocalDateTime ldt3 = ld2.plusYears(20);
		System.out.println(ldt3);
		LocalDateTime ldt4 = ld2.minusMonths(2);
		System.out.println(ldt4);
		System.out.println(ldt.getYear());
		System.out.println(ldt.getMonthValue());
		System.out.println(ldt.getDayOfMonth());
		System.out.println(ldt.getHour());
		System.out.println(ldt.getMinute());
		System.out.println(ldt.getSecond());
}

4.Instant : 時間戳

用於“時間戳”的運算。它是以Unix元年(傳統的設定為UTC時區197011日午夜時分)開始所經歷的描述進行運算

@Test
public void test2(){
		Instant ins = Instant.now();  //預設使用 UTC 時區
		System.out.println(ins);
		
		OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
		System.out.println(odt);
		
		System.out.println(ins.getNano());
		
		Instant ins2 = Instant.ofEpochSecond(5);
		System.out.println(ins2);
}

5.Duration 和 Period

Duration:用於計算兩個“時間”間隔
Period:用於計算兩個“日期”間隔

     //Duration : 用於計算兩個“時間”間隔
	//Period : 用於計算兩個“日期”間隔
	@Test
	public void test3(){
		Instant ins1 = Instant.now();
		System.out.println("--------------------");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
		}
		Instant ins2 = Instant.now();
		Duration	duration=Duration.between(ins1, ins2);
		System.out.println( duration);
		System.out.println(  duration.getNano());
		System.out.println( duration.getSeconds());
		System.out.println( duration.getUnits());
		System.out.println("----------------------------------");
		LocalDate ld1 = LocalDate.now();
		LocalDate ld2 = LocalDate.of(2011, 1, 1);
		
		Period pe = Period.between(ld2, ld1);
		System.out.println(pe.getYears());
		System.out.println(pe.getMonths());
		System.out.println(pe.getDays());
	}


6.日期的操縱

TemporalAdjuster :時間校正器。有時我們可能需要獲取例如:將日期調整到“下個週日”等操作。

TemporalAdjusters: 該類通過靜態方法提供了大量的常用TemporalAdjuster 的實現

 TemporalAdjuster : 時間校正器
	@Test
	public void test4(){
	LocalDateTime ldt = LocalDateTime.now();
		System.out.println(ldt);
		LocalDateTime ldt2 = ldt.withDayOfMonth(10);
		System.out.println(ldt2);
		LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
		System.out.println(ldt3);
		//自定義:下一個工作日
		LocalDateTime ldt5 = ldt.with((l) -> {
			LocalDateTime ldt4 = (LocalDateTime) l;
			DayOfWeek dow = ldt4.getDayOfWeek();
			if(dow.equals(DayOfWeek.FRIDAY)){
				return ldt4.plusDays(3);
			}else if(dow.equals(DayOfWeek.SATURDAY)){
				return ldt4.plusDays(2);
			}else{
				return ldt4.plusDays(1);
			}
		});
		System.out.println(ldt5);
	}

7.解析與格式化

java.time.format.DateTimeFormatter 類:該類提供了三種

格式化方法:

 預定義的標準格式

 語言環境相關的格式

 自定義的格式

	@Test
	public void test5(){
		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E");
		LocalDateTime ldt = LocalDateTime.now();
		String strDate = ldt.format(dtf);
		System.out.println(strDate);
		LocalDateTime newLdt = ldt.parse(strDate, dtf);
		System.out.println(newLdt);
	}

8.時區的處理

Java8 中加入了對時區的支援,帶時區的時間為分別為:ZonedDate、 ZonedTime、 ZonedDateTime
其中每個時區都對應著 ID,地區ID都為 “{區域}/{城市}”的格式
例如 : Asia/Shanghai 等
ZoneId:該類中包含了所有的時區資訊
getAvailableZoneIds() : 可以獲取所有時區時區資訊
of(id) : 用指定的時區資訊獲取 ZoneId 物件 

@Test
public void test7(){
		LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
		System.out.println(ldt);
		
		ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("US/Pacific"));
		System.out.println(zdt);
}
https://www.cnblogs.com/exmyth/p/6425878.html