1. 程式人生 > >java8時間日期API(LocalDate、 LocalTime、 Instant、 Duration 以及 Period)

java8時間日期API(LocalDate、 LocalTime、 Instant、 Duration 以及 Period)

  1. 建立一個LocalDate物件並讀取其值
LocalDate date = LocalDate.of(2018, 10, 31);//2018-10-31
int year = date.getYear();//2018
Month month = date.getMonth();//OCTOBER
int day = date.getDayOfMonth();//31
DayOfWeek dow = date.getDayOfWeek();//WEDNESDAY
int len = date.lengthOfMonth();//31
boolean leap = date.isLeapYear();//false
  1. 獲取當前的日期
LocalDate today = LocalDate.now();
  1. 使用TemporalField讀取LocalDate的值
int year = date.get(ChronoField.YEAR);
int month = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);
  1. 建立LocalTime並讀取其值
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
  1. LocalDate和LocalTime都可以通過解析代表它們的字串建立
LocalDate date = LocalDate.parse("2018-10-31");
LocalTime time = LocalTime.parse("13:45:20");
  1. 合併日期和時間 LocalDateTime
	@Test
	public void test2() {
		LocalDate date = LocalDate.of(2018, 10, 31);
		LocalTime time = LocalTime.of(13, 45, 20);
		// 2018-10-31T13:45:20
		LocalDateTime dt1 = LocalDateTime.of(2018, Month.OCTOBER, 31, 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);
	}
  1. 從LocalDateTime中提取LocalDate或者LocalTime元件
LocalDate date1 = dt1.toLocalDate();//2018-10-31
LocalTime time1 = dt1.toLocalTime();//13:45:20

8.機器的日期和時間格式 Instant

java.time.Instant類對時間建模的方式,以Unix元年時間(傳統的設定為UTC時區1970年1月1日午夜時分)開始所經歷的秒數進行計算.

Instant.ofEpochSecond(3);
Instant.ofEpochSecond(3, 0);
Instant.ofEpochSecond(2, 1_000_000_000);//2 秒 之 後 再 加 上100萬納秒( 1秒)
Instant.ofEpochSecond(4, -1_000_000_000);//4秒之前的100萬納秒( 1秒)
int day = Instant.now().get(ChronoField.DAY_OF_MONTH);
//java.time.temporal.UnsupportedTemporalTypeException: Unsupported field:DayOfMonth

它包含的是由秒及納秒所構成的數字。所以,它無法處理那些我們非常容易理解的時間單位。但是可以通過Duration和Period類使用Instant.

定義 Duration 或 Period

	@Test
	public void test4() {
		Period tenDays = Period.between(LocalDate.of(2018, 10, 21),
				LocalDate.of(2018, 10, 31));
		System.out.println(tenDays.getDays());//10
	}

建立Duration和Period物件

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);

日期-時間類中表示時間間隔的通用方法

方 法 名 是否是靜態方法 方法描述
between 建立兩個時間點之間的 interval
from 由一個臨時時間點建立 interval
of 由它的組成部分建立 interval 的例項
parse 由字串建立 interval 的例項
addTo 建立該 interval 的副本,並將其疊加到某個指定的 temporal 物件
get 讀取該 interval 的狀態
isNegative 檢查該 interval 是否為負值,不包含零
isZero 檢查該 interval 的時長是否為零
minus 通過減去一定的時間建立該 interval 的副本
multipliedBy 將 interval 的值乘以某個標量建立該 interval 的副本
negated 以忽略某個時長的方式建立該 interval 的副本
plus 以增加某個指定的時長的方式建立該 interval 的副本
subtractFrom 從指定的 temporal 物件中減去該 interval

操縱、解析和格式化日期

	@Test
	public void test5() {
		LocalDate date1 = LocalDate.of(2018, 10, 31);//2018-10-31
		LocalDate date2 = date1.withYear(2011);//2011-10-31
		LocalDate date3 = date2.withDayOfMonth(25);//2011-10-25
		LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9);//2011-09-25
	}

以相對方式修改LocalDate物件的屬性

	@Test
	public void test6() {
		LocalDate date1 = LocalDate.of(2018, 10, 31);//2018-10-31
		LocalDate date2 = date1.plusWeeks(1);//2018-11-07
		LocalDate date3 = date2.minusYears(3);//2015-11-07
		LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);//2016-05-07
	}
	

表示時間點的日期時間類的通用方法

方 法 名 是否是靜態方法 方法描述
from 依據傳入的 Temporal 物件建立物件例項
now 依據系統時鐘建立 Temporal 物件
of 由 Temporal 物件的某個部分建立該物件的例項
parse 由字串建立 Temporal 物件的例項
atOffset 將 Temporal 物件和某個時區偏移相結合
atZone 將 Temporal 物件和某個時區相結合
format 使用某個指定的格式器將Temporal 物件轉換為字串(Instant 類不提供該方法)
get 讀取 Temporal 物件的某一部分的值
minus 建立 Temporal 物件的一個副本,通過將當前 Temporal 物件的值減去一定的時長建立該副本
plus 建立 Temporal 物件的一個副本,通過將當前 Temporal 物件的值加上一定的時長建立該副本
with 以該 Temporal 物件為模板,對某些狀態進行修改建立該物件的副本

使用 TemporalAdjuster

	@Test
	public void test7() {
		LocalDate date1 = LocalDate.of(2018, 10, 31);//2018-10-31
		LocalDate date2 = date1.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));//2018-11-04
		LocalDate date3 = date2.with(TemporalAdjusters.lastDayOfMonth());//2018-11-30
	}

TemporalAdjuster類中的工廠方法

方 法 名 方法描述
dayOfWeekInMonth 建立一個新的日期,它的值為同一個月中每一週的第幾天
firstDayOfMonth 建立一個新的日期,它的值為當月的第一天
firstDayOfNextMonth 建立一個新的日期,它的值為下月的第一天
firstDayOfNextYear 建立一個新的日期,它的值為明年的第一天
firstDayOfYear 建立一個新的日期,它的值為當年的第一天
firstInMonth 建立一個新的日期,它的值為同一個月中,第一個符合星期幾要求的值
lastDayOfMonth 建立一個新的日期,它的值為當月的最後一天
lastDayOfNextMonth 建立一個新的日期,它的值為下月的最後一天
lastDayOfNextYear 建立一個新的日期,它的值為明年的最後一天
lastDayOfYear 建立一個新的日期,它的值為今年的最後一天
lastInMonth 建立一個新的日期,它的值為同一個月中,最後一個符合星期幾要求的值
next/previous 建立一個新的日期,並將其值設定為日期調整後或者調整前,第一個符合指定星期幾要求的日期
nextOrSame/previousOrSame 建立一個新的日期,並將其值設定為日期調整後或者調整前,第一個符合指定星期幾要求的日期,如果該日期已經符合要求,直接返回該物件

TemporalAdjuster介面

	@Test
	public void test8() {
		LocalDate date = LocalDate.of(2018, 10, 31);
		date = date.with(temporal -> {
			DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
			int dayToAdd = 1;
			if (dow == DayOfWeek.FRIDAY)
				dayToAdd = 3;
			else if (dow == DayOfWeek.SATURDAY)
				dayToAdd = 2;
			return temporal.plus(dayToAdd, ChronoUnit.DAYS);
		});
		System.out.println(date);//2018-11-01
	}

列印輸出及解析日期時間物件

	@Test
	public void test8() {
		LocalDate date = LocalDate.of(2018, 10, 31);
		String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE);
		String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
		System.out.println(s1);//	20181031
		System.out.println(s2);//2018-10-31

		LocalDate date1 = LocalDate.parse("20181031", DateTimeFormatter.BASIC_ISO_DATE);
		LocalDate date2 = LocalDate.parse("2018-10-31", DateTimeFormatter.ISO_LOCAL_DATE);
		System.out.println(date1 );//	2018-10-31
		System.out.println(date1 );//2018-10-31
	}
	@Test
	public void test9() {
		LocalDate date = LocalDate.of(2018, 10, 31);//2018-10-31
		DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.CHINA);
		LocalDate date1 = LocalDate.of(2018, 10, 31);//2018-10-31
		String formattedDate = date.format(italianFormatter); // 31 - 十月 - 2018
		LocalDate date2 = LocalDate.parse(formattedDate, italianFormatter);//2018-10-31
	}


	@Test
	public void test10() {
		LocalDate date = LocalDate.of(2018, 10, 31);//2018-10-31
		
		DateTimeFormatter italianFormatter = new DateTimeFormatterBuilder()
				.appendText(ChronoField.DAY_OF_MONTH)
				.appendLiteral("-")
				.appendText(ChronoField.MONTH_OF_YEAR)
				.appendLiteral("-")
				.appendText(ChronoField.YEAR)
				.parseCaseInsensitive()
				.toFormatter(Locale.CHINA);
		String format = date.format(italianFormatter);//31-十月-2018
		LocalDate parse = LocalDate.parse(format, italianFormatter);//2018-10-31
	}

處理不同的時區和曆法

	/**
	Europe/Rome
	Asia/Shanghai
	2018-10-31
	2018-10-31T00:00+01:00[Europe/Rome]
	2018-10-31T13:45
	2018-10-31T13:45+01:00[Europe/Rome]
	2018-11-05T09:16:33.478Z
	2018-11-05T10:16:33.478+01:00[Europe/Rome]

	*/
	@Test
	public void test11() {
		ZoneId romeZone = ZoneId.of("Europe/Rome");
		
		ZoneId zoneId = TimeZone.getDefault().toZoneId();
		
		
		LocalDate date = LocalDate.of(2018, Month.OCTOBER, 31);
		ZonedDateTime zdt1 = date.atStartOfDay(romeZone);
		LocalDateTime dateTime = LocalDateTime.of(2018, Month.OCTOBER, 31, 13, 45);
		ZonedDateTime zdt2 = dateTime.atZone(romeZone);
		Instant instant = Instant.now();
		ZonedDateTime zdt3 = instant.atZone(romeZone);
		
		System.out.println(romeZone);
		System.out.println(zoneId);
		System.out.println(date);
		System.out.println(zdt1);
		System.out.println(dateTime);
		System.out.println(zdt2);
		System.out.println(instant);
		System.out.println(zdt3);
	}

LocaleDate、LocalTime、 LocalDateTime以及ZoneId之間的差異。 在這裡插入圖片描述