Java8提供的新的時間日期的類型LocalDate,LocalTime,LocalDateTime。之前用的Date和Calendar都為線程不安全。用來格式化Date類型的SimpleDateFormat也是線程不安全的。LocalDate和格式化LocalDate的DateTimeFormatter是線程安全的。
LocalDate的使用
創建LocalDate對象有兩種方式:
// 創建當前日期的LocalDate
LocalDate localDate = LocalDate.now();
// 創建指定日期的LocalDate
LocalDate localDate1 = LocalDate.of(2020,4,14);
從LocalDate類型的對象中獲取年,月,日,星期幾
獲取年月日周幾都是有兩種方式,一個getXxx()
,一種get(ChronoField.XXX)
// 獲取年
int year = localDate.getYear();
int year1 = localDate.get(ChronoField.YEAR);
System.out.println(year + " -- " + year1); // 2020 -- 2020
// 獲取月
Month month = localDate.getMonth();
int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
System.out.println("month = " + month); // month = APRIL
System.out.println("month.getValue() = " + month.getValue()); // month.getValue() = 4
System.out.println("month1 = " + month1); // month1 = 4
// Month類型也可以做加減法,month.plus(1),會返回一個Month對象,值為MAY
// 獲取日,DayOfMonth
int day = localDate.getDayOfMonth();
int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
System.out.println("day-day1 = " + day + " - " + day1);// day-day1 = 16 - 16
// 獲取周幾,DayOfWeek
DayOfWeek dayOfWeek = localDate.getDayOfWeek();
int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);
System.out.println("dayOfWeek = " + dayOfWeek); // THURSDAY
System.out.println("dayOfWeek.getValue()="+dayOfWeek.getValue());//dayOfWeek.getValue()=4
System.out.println("dayOfWeek1 = " + dayOfWeek1);// dayOfWeek1 = 4
// DayOfWeek也可以做加減法,具體方法.就能看到
LocalTime的使用
LocalTime localTime = LocalTime.now();
LocalTime localTime1 = LocalTime.of(13, 51, 10);
//獲取小時
int hour = localTime.getHour();
int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
//獲取分
int minute = localTime.getMinute();
int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
//獲取秒
int second = localTime.getSecond();
int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
LocalDateTime的使用
// LocalDateTime就是LocalDate+LocalTime
// 創建LocalDateTime的幾種方式
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2020, Month.APRIL, 4, 14, 46, 56);
LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
LocalDateTime localDateTime3 = localDate.atTime(localTime);
LocalDateTime localDateTime4 = localTime.atDate(localDate);
// 從LocalDateTime獲取LocalDate和LocalTime
LocalDate localDate4 = localDateTime.toLocalDate();
LocalTime localTime2 = localDateTime.toLocalTime();
Instant的使用
// 創建Instant對象
Instant instant = Instant.now();
// 獲取秒數
long epochSecond = instant.getEpochSecond();
// 獲取毫秒 也可以用System.currentTimeMillis();
long currentMilli = instant.toEpochMilli();
格式化LocalDate和解析字符串到LocalDate
// 格式化時間 DateTimeFormatter是線程安全的,SimpleDateFormat是線程不安全的
// 使用DateTimeFormatter提供的默認的模板
String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE); // yyyyMMdd
String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE); // yyyy-MM-dd
//自定義格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String s3 = localDate.format(dateTimeFormatter);
// 解析時間
LocalDate localDate5 = LocalDate.parse("20200414", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate6 = LocalDate.parse("2020-04-14", DateTimeFormatter.ISO_LOCAL_DATE);
LocalDate的加減法
LocalDate的加減法,有加減天數,月,周,年
對應的方法是plusDays(long),plusMonths(long),plusYears(long),plusWeeks(long),plus(1, ChronoUnit.YEARS)
,
minusDays(long),minusMonths(long),minusYears(long),minusWeeks(long),minus(1, ChronoUnit.MONTHS)
。
具體的方法和方法簽名,直接.也能看到。
// 今天是2020-04-16
LocalDate localDate2 = localDate.plusDays(10);
System.out.println("localDate2.toString() = " + localDate2.toString());
LocalDate localDate3 = localDate.minusMonths(1);
System.out.println("localDate3.toString() = " + localDate3.toString());
通過with修改某些值
只修改年,不修改月日
LocalDate localDate = LocalDate.now();
//修改年為2021
localDate = localDate.withYear(2021);
//修改為2022
localDate = localDate.with(ChronoField.YEAR, 2022);
有些時候想知道這個月的最后一天是幾號、下個周末是幾號,通過提供的時間和日期API可以很快得到答案。
使用TemporalAdjusters中的一些提供的方法:
LocalDate localDate7 = LocalDate.now();
localDate7 = localDate7.with(TemporalAdjusters.firstDayOfYear());
跟着LocalDate中with方法往下讀的一些源碼
在LocalDate的源碼中,with有這么一些方法:
// with方法,需要一個 TemporalAdjuster類型的對象,
public LocalDate with(TemporalAdjuster adjuster) {
/*
LocalDate實現了TemporalAdjuster接口,這里也能直接傳入LocalDate的對象。看這個方法中的邏輯可以明白,如果adjuster是LocalDate的實例,那么強轉為LocalDate類型。
如果不傳入LocalDate類型的,只需要傳入實現了TemporalAdjuster接口的對象,會調用TemporalAdjuster中的adjustInto方法。可以看到TemporalAdjuster的adjuster方法返回的是Temporal類型的對象,強轉為LocalDate類型。
*/
return adjuster instanceof LocalDate ? (LocalDate)adjuster : (LocalDate)adjuster.adjustInto(this);
}
public LocalDate with(TemporalField field, long newValue) {
if (field instanceof ChronoField) {
ChronoField f = (ChronoField)field;
f.checkValidValue(newValue);
switch(f) {
case DAY_OF_MONTH:
return this.withDayOfMonth((int)newValue);
case DAY_OF_YEAR:
return this.withDayOfYear((int)newValue);
// 這里還有很多case語句,省略...
} else {
return (LocalDate)field.adjustInto(this, newValue);
}
}
// 下面這些都是替換具體的int的值
public LocalDate withYear(int year){//...
}
public LocalDate withMonth(int month){//...
}
public LocalDate withDayOfMonth(int dayOfMonth){//...
}
public LocalDate withDayOfYear(int dayOfYear){//...
}
在TemporalAdjusters這個類中,有許多的方法,都是返回一個實現好的TemporalAdjuster的引用類型
public static TemporalAdjuster firstDayOfYear() {
return (temporal) -> {
return temporal.with(ChronoField.DAY_OF_YEAR, 1L);
};
}
public static TemporalAdjuster lastDayOfYear() {
return (temporal) -> {
return temporal.with(ChronoField.DAY_OF_YEAR, temporal.range(ChronoField.DAY_OF_YEAR).getMaximum());
};
}
參考: