JDK8新特性:日期時間相關API

JDK8新特性:日期時間相關API


舊版日期時間API存在的問題:

  • 1.設計很差:在 java.tilogjava sq| 的包中都有日期類,java.util.Date同時包含日期和時間,而 java.sql.Date 僅。包含日期。此外用於格式化和解析的類在 java.text 包中定義。
  • 2.非線程安全:java.util.Date 是非線程安全的,所有的日期類都是可變的,這是Java日期類最大的問題之一。
  • 3.時區處理麻煩:日期類並不提供國際化,沒有時區支持。因此ava引入了 java.util.Calendarjava.util.TimeZone 類, 但他們同樣存在上述所有的問題。

新日期時間API介紹

JDK 8中增加了一套全新的日期時間API,這套API設計合理,是線程安全的。

  • java.time - 包含值對象的基礎包
  • java.time.chrono - 提供不同日曆系統的訪問
  • java.time.format - 格式化和解析時間和日期
  • java.time.temporal - 包含底層框架和擴展特性
  • java.time.zone - 包含時區支持的類

新的日期及時間API位於java.time包中,下面是一些關鍵類:

  • LocalDate:表示日期,包含年月日.格式爲2019-10-16
  • LocalTime:表示時間,包含時分秒,格式爲16:38:54.158549300
  • LocalDateTime:表示日期時間,包含年月日,時分秒,格式爲2018-09-06T15:33:56.750
  • DateTimeFormatter:日期時間格式化類。
  • Instant:時間戳,表示一個特定的時間瞬間。
  • Duration:用於計算2個時間(LocalTime, 時分秒)的距離
  • Period:用於計算2個日期(LocalDate, 年月日)的距離
  • zonedDaterime:包含時區的時間

Java中使用的歷法是ISO 8601日曆系統,它是世界民用曆法,也就是我們所說的公曆。平年有365天.閏年是366天。此外ava 8還提供了4套其他曆法,分別是:

  • ThaiBuddhistDate: 泰國佛教歷
  • MinguoDate: 中華民國曆
  • JapaneseDate:日本歷
  • HijrahDate: 伊斯蘭曆

LocalDateTime、LocalDate、LocalTime常用方法

LocalDateTime = LocalDate + LocalTime

(1.)獲取默認時區的當前時間
LocalDate localdate  = LocalDate.now();  --獲取時間:年月日
LocalTime localtime  = LocalTime.now();  --獲取時間:時分秒
LocalDateTime localdatetime  = LocalDateTime.now();  --獲取時間:年月日時分秒

--結果:
localdate = 2020-06-16
localtime = 17:35:13.788
localdatetime = 2020-06-16T17:35:13.789

(2)指定具體的日期時間
LocalDateTime dateTime = LocalDateTime.of(2089, 12, 25, 12, 30, 30); -- 年月日時分秒
LocalDate date = LocalDate.of(2089, 12, 25); -- 年月日
LocalTime time1 = LocalTime.of(12, 30); -- 時分
LocalTime time2 = LocalTime.of(12, 30, 30); -- 時分秒
LocalTime time3 = LocalTime.of(12, 30, 30, 150); -- 時分秒納秒

-- 結果
dateTime:2089-12-25T12:30:30
date:2089-12-25
time1:12:30
time2:12:30:30
time3:12:30:30.000000150

(3)獲取具體的年月日時分秒、星期、天數等

這裏爲 LocalDateLocalTime 分開使用,也可以直接使用 LocalDateTime

LocalDate of = LocalDate.now();
System.out.println("年 = " + of.getYear());
System.out.println("月(英文) = " + of.getMonth());
System.out.println("月(數字) = " + of.getMonthValue());
System.out.println("這個月的第幾天 = " + of.getDayOfMonth());
System.out.println("一年中的第幾天 = " + of.getDayOfYear());
System.out.println("星期 = " + of.getDayOfWeek());

LocalTime nowTime = LocalTime.now();
System.out.println("時:" + nowTime.getHour());
System.out.println("分:" + nowTime.getMinute());
System.out.println("秒:" + nowTime.getSecond());
System.out.println("納秒:" + nowTime.getNano());

(4)日期大小判斷

這裏的 isBeforeisAfter 比較都是後一個減去前一個,如果後面一個大,返回的是正數,否則是負數

LocalDate date1 = LocalDate.of(2020, 11, 30);
LocalDate date2 = LocalDate.of(2089, 12, 25);

System.out.println(date1.isBefore(date2));
System.out.println(date1.isAfter(date2));
System.out.println(date1.equals(date2));
System.out.println(date.isLeapYear()); -- 是否是閏年

(5)某個月或者某年有多少天
System.out.println(date1.lengthOfMonth()); -- 判斷這個月有多少天
System.out.println(date1.lengthOfYear()); -- 判斷年份有多少天

(6)直接修改、增加、減少年月日時分秒
-- 修改
LocalDateTime dateTime1 = LocalDateTime.of(2089, 12, 25, 12, 30, 30);
System.out.println("設置年份:" + dateTime1.withYear(1991));
System.out.println("設置月份:" + dateTime1.withMonth(5));
System.out.println("設置小時:" + dateTime1.withHour(3));
System.out.println("設置分鐘:" + dateTime1.withMinute(25));
System.out.println("設置秒:" + dateTime1.withSecond(26));
System.out.println("設置這個月的第多少天:" + dateTime1.withDayOfMonth(20));
System.out.println("設置這一年的第多少天:" + dateTime1.withDayOfYear(100));

-- 增加
System.out.println("增加年:" + dateTime1.plusYears(3));
System.out.println("增加月:" + dateTime1.plusMonths(5));
System.out.println("增加天:" + dateTime1.plusDays(3));
System.out.println("增加小時:" + dateTime1.plusHours(2));
System.out.println("增加分鐘:" + dateTime1.plusMinutes(26));
System.out.println("增加秒:" + dateTime1.plusSeconds(20));

-- 減少
System.out.println("減少年:" + dateTime1.minusYears(3));
System.out.println("減少月:" + dateTime1.minusMonths(5));
System.out.println("減少天:" + dateTime1.minusDays(3));
System.out.println("減少小時:" + dateTime1.minusHours(2));
System.out.println("減少分鐘:" + dateTime1.minusMinutes(26));
System.out.println("減少秒:" + dateTime1.minusSeconds(20));

(7)時間類型轉換
LocalDateTime dateTime1 = LocalDateTime.of(2089, 12, 25, 12, 30, 30);
LocalDate date = LocalDate.of(2089, 12, 25);
LocalTime time= LocalTime.of(12, 30, 30);

System.out.println(dateTime1.toLocalTime()); -- LocalDateTime轉LocalTime
System.out.println(dateTime1.toLocalDate()); -- LocalDateTime轉LocalDate
System.out.println(date.atTime(time)); -- LocalDate和LocalTime轉LocalDateTime
System.out.println(time.atDate(date)); -- LocalDate和LocalTime轉LocalDateTime

-- 結果
12:30:30
2089-12-25
2089-12-25T12:30:30
2089-12-25T12:30:30

日期解析和格式化:DateTimerFormatter

LocalDateTime dateTime = LocalDateTime.of(2089, 12, 25, 12, 30, 30);
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

-- 正反都能調用format方法
String date1 = dateTime.format(dtf);
System.out.println(date1);
String date2 = dtf.format(dateTime);
System.out.println(date2);

-- 結果
2089-12-25 12:30:30
2089-12-25 12:30:30

計算日期時間差 Duration 和 Period

  • Duration
LocalDateTime today = LocalDateTime.now();
LocalDateTime dateTime = LocalDateTime.of(2089, 12, 25, 12, 30, 30);

Duration duration = Duration.between(today, dateTime); 
System.out.println(duration.toDays());    -- 相差的天數
System.out.println(duration.toHours());   -- 相差的小時數
System.out.println(duration.toMinutes()); -- 相差的分鐘數
System.out.println(duration.toMillis());  -- 相差的毫秒數
System.out.println(duration.toNanos());   -- 相差的納秒數
  • Period
LocalDate today = LocalDate.now();
LocalDate date = LocalDate.of(2089, 12, 25);

Period period = Period.between(today, date);
System.out.println(period.getYears());  -- 相差多少年
System.out.println(period.getMonths()); -- 相差多少月
System.out.println(period.getDays());   -- 相差多少天

時間調整器:TemporalAdjuster 和 TemporalAdjusters

TemporalAdjuster 是函數式接口,可自定義調整;
TemporalAdjusters 是針對 TemporalAdjuster 的工具類,內置了很多方法
在這裏插入圖片描述


例子:

-- 調整到下一年的第一天
LocalDateTime dateTime = LocalDateTime.of(2089, 12, 25, 12, 30, 30);
LocalDateTime with = dateTime.with(TemporalAdjusters.firstDayOfNextYear());
System.out.println("with = " + with);

-- 結果
with = 2090-01-01T12:30:30

時間戳:Instant

Instant instant = Instant.now(); -- 得到當前時間到 1970-01-01 00:00:00 的毫秒值
System.out.println(instant);
System.out.println("秒數:" + instant .getEpochSecond());
System.out.println("毫秒數:" + instant .toEpochMilli());

這裏的 Instant.now() 方法默認使用UTC時間,而不是系統默認時間。點進源碼即可看到


時區相關:ZoneID、ZonedDateTime

--獲取世界各個地方的時區集合
ZoneId.getAvailableZoneIds().forEach(System.out::println);

ZonedDateTime now = ZonedDateTime.now();-- 系統默認時區
ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());-- 標準時區 UTC
ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));--通過ZoneId指定時區
System.out.println("now = " + now);
System.out.println("now1 = " + now1);
System.out.println("now2 = " + now2);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章