天天看點

Jdk8 時間和日期API介紹

在項目開發中,需要對 Date 類型進行格式,否則可讀性很差,格式化 Date 類型常用類卻是 SimpleDateFormat,而在多線程環境下 SimpleDateFormat 可能會出現總是想不到的問題,因為 SimpleDateFormat 是線程不安全的,在多線程下建議使用 DateTimeFormatter 格式化日期

Java8 日期和時間API中提供了3個時間類,分别是:LocalDate、LocalTime、LocalDateTime,絕大多數操作都是圍繞這幾個對象來進行的。

LocalDateTime與Date差別:Date有的LocalDateTime都有,Date沒有的LocalDateTime也有。

下面列舉的都是常用,想要了解更多請參考API文檔。

LocalDate

LocalDate 是日期處理類,隻含年月日的日期對象,LocalDate是不可變并且線程安全的。常用操作如下:

// 擷取目前日期
LocalDate localDate = LocalDate.now();
System.out.println(localDate);

// 根據指定日期/時間建立對象
localDate = LocalDate.of(2022, 8, 3);
System.out.println(localDate);

// 擷取年
System.out.println(localDate.getYear());
System.out.println(localDate.get(ChronoField.YEAR));

// 擷取月
System.out.println(localDate.getMonth());
System.out.println(localDate.get(ChronoField.MONTH_OF_YEAR));

// 擷取日
System.out.println(localDate.getDayOfMonth());
System.out.println(localDate.get(ChronoField.DAY_OF_MONTH));

// 擷取星期
System.out.println(localDate.getDayOfWeek());
System.out.println(localDate.getDayOfWeek().getValue());
System.out.println(localDate.get(ChronoField.DAY_OF_WEEK));

// 在目前時間基礎上指定本年中的第幾天,取值範圍1-366
System.out.println(localDate.withDayOfYear(10));
// 在目前時間基礎上指定本月中的第幾天,取值範圍1-31
System.out.println(localDate.withDayOfMonth(20));      

LocalTime

LocalTime 是時間處理類,隻含時分秒的時間對象,LocalTime是不可變并且線程安全的。常用操作如下:

// 擷取目前時間
LocalTime localTime = LocalTime.now();
System.out.println(localTime);

// 設定時間
localTime = LocalTime.of(13, 51, 10);
System.out.println(localTime);

//擷取小時
System.out.println(localTime.getHour());
System.out.println(localTime.get(ChronoField.HOUR_OF_DAY));

//擷取分
System.out.println(localTime.getMinute());
System.out.println(localTime.get(ChronoField.MINUTE_OF_HOUR));

//擷取秒
System.out.println(localTime.getSecond());
System.out.println(localTime.get(ChronoField.SECOND_OF_MINUTE));      

LocalDateTime

LocalDateTime 可以設定年月日時分秒,同時含有年月日時分秒的日期對象,相當于LocalDate + LocalTime;LocalDateTime是不可變并且線程安全的。常用操作如下:

// 擷取目前日期時間
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);

// 擷取LocalDate
LocalDate localDate = localDateTime.toLocalDate();
System.out.println(localDate);

// 擷取LocalTime
LocalTime localTime = localDateTime.toLocalTime();
System.out.println(localTime);

// 設定日期
localDateTime = LocalDateTime.of(2022, 8, 10, 14, 46, 56);
System.out.println(localDateTime);

localDateTime = LocalDateTime.of(localDate, localTime);
System.out.println(localDateTime);

// 日期時間的加減
System.out.println(localDateTime.plusYears(2L));
System.out.println(localDateTime.plus(2, ChronoUnit.MONTHS));

// 擷取日期的年月日周
System.out.println(localDateTime.getDayOfYear());
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getDayOfWeek().getValue());

//增加一年
System.out.println(localDateTime.plusYears(1));
System.out.println(localDateTime.plus(1, ChronoUnit.YEARS));
//減少一個月
System.out.println(localDateTime.minusMonths(1));
System.out.println(localDateTime.minus(1, ChronoUnit.MONTHS));


// 修改年
System.out.println(localDateTime.withYear(2021));
System.out.println(localDateTime.with(ChronoField.YEAR, 2022));

// 日期計算
// 通過 TemporalAdjusters 類提供的方法擷取年月周的開始和結束時間,
LocalDate localDate1 = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
System.out.println(localDate1);

//  格式化時間
localDate = LocalDate.of(2019, 9, 10);
System.out.println(localDate.format(DateTimeFormatter.BASIC_ISO_DATE));
System.out.println(localDate.format(DateTimeFormatter.ISO_LOCAL_DATE));

//自定義格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
System.out.println(localDate.format(dateTimeFormatter));

// 解析時間
System.out.println(LocalDate.parse("20220803", DateTimeFormatter.BASIC_ISO_DATE));
System.out.println(LocalDate.parse("2021-08-03", DateTimeFormatter.ISO_LOCAL_DATE));      

Duration

Duration 用于計算兩個日期的“時間”間隔。常用操作如下:

// 計算兩個時間的間隔
LocalDateTime localDateTime1 = LocalDateTime.now();
LocalDateTime localDateTime2 = LocalDateTime.of(2022, 5, 13, 22, 30, 10);

Duration duration = Duration.between(localDateTime1, localDateTime2);

System.out.println(" 天 :" + duration.toDays());
System.out.println(" 時 :" + duration.toHours());
System.out.println(" 分 :" + duration.toMinutes());
System.out.println(" 毫秒 :" + duration.toMillis());      

Period

// 計算兩個日期的間隔
LocalDate localDate1 = LocalDate.of(2022, 5, 20);
LocalDate localDate2 = LocalDate.of(2022, 8, 3);

// 内部是用date2-date1,是以得到的結果是負數
Period period = Period.between(localDate1, localDate2);

System.out.println("相差年數 : " + period.getYears());
System.out.println("相差月數 : " + period.getMonths());
System.out.println("相差日數 : " + period.getDays());
// 或
System.out.println("相差年數 : " + period.get(ChronoUnit.YEARS));
System.out.println("相差月數 : " + period.get(ChronoUnit.MONTHS));
System.out.println("相差日數 : " + period.get(ChronoUnit.DAYS));      

Date與LocalDateTime轉換

// datetime轉字元串
String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(format);

// 字元串轉datetime
LocalDateTime localDateTime = LocalDateTime.parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(localDateTime);

// LocalDateTime轉date
Date date1 = Date.from(localDateTime.toInstant(ZoneOffset.ofHours(8)));
System.out.println(date1);

Date date2 = Date.from(Instant.from(localDateTime.atZone(ZoneId.systemDefault())));
System.out.println(date2);

Date date3 = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println(date3);
System.out.println();

// date轉LocalDateTime
LocalDateTime localDateTime1 = date1.toInstant().atOffset(ZoneOffset.ofHours(8)).toLocalDateTime();
System.out.println(localDateTime1);

LocalDateTime localDateTime2 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(localDateTime2);

// LocalDateTime轉毫秒時間戳
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
long timestamp = instant.toEpochMilli();
System.out.println(timestamp);

// 時間戳轉LocalDateTime
System.out.println(LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()));      

繼續閱讀