玩轉Java8日期工具類-基礎

內容基於的是 Java8官方文檔,以及Java時間類總結 的總結。BTW:其實具體方法的使用直接在IDEA中看源碼更方便直接。

1.老一輩:Java.util.Date Java.sql.Date Java.util.Calendar

1.1 Java.util.Date

最經典的表示時間的類,包含年月日時分秒,精確到毫秒級別,保留兩個沒被廢棄的構造方法

Date nowDate = new Date();
System.out.println("現在時間: " + nowDate);
//結果打印當前時間 「現在時間: Sat Aug 14 17:38:49 CST 2021」
//上面其實是返回了此時毫秒時間最接近的秒時間

long nowDateMS = nowDate.getTime();
//填入long類型的 January 1, 1970, 00:00:00 GMT到某個時間的毫秒數
Date nowDatePlus1000s = new Date(nowDateMS + 1000*1000);
System.out.println(nowDatePlus1000s);
//結果是: "Sat Aug 14 17:55:29 CST 2021"

常用方法:

//返回該時間點到January 1, 1970, 00:00:00 GMT的毫秒數
date.getTime()
//判斷兩個時間的前後,返回值為int類,前者早於後者返回-1;等則為0,晚則為1
date.compareTo(Date anotherDate)
//判斷兩個時間的前後,返回值為boolean,通過比較距離1970那個時間的毫秒數的大小判斷
date.before(Date anotherDate)
date.after(Date anotherDate)

Date類型藉助 java.text.SimpleDateFormat 實現格式化,返回值是 String。同時也逆向解析字符串對應的字符串,返回Date類,但是要保持格式一致,否則返回null

////格式化
SimpleDateFormat sdf12 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // hh表示12小時制
SimpleDateFormat sdf24 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // HH表示24小時制

String date1 = sdf12.format(nowDate);
System.out.println(date1);
//結果: 2021-08-14 06:41:54

String date2 = sdf24.format(nowDate);
System.out.println(date2)
//結果: 2021-08-14 18:41:54
        
////解析 字符串格式必須是 "yyyy-MM-dd HH:mm:ss" 類型才可成功,也就是你是怎麼轉過去的,就怎麼轉回來,確保一一對應,否則返回null
Date date3 = sdf24.parse(date2, new ParsePosition(0)); // ParsePosition(0) 表示解析全部的字符串。

1.2 Java.sql.Date

java.sql.Date extends java.util.Date,二者區別不大,值得注意只有毫秒的構造函數。它主要對應於SQL中的DATE類型,因此將時分秒,毫秒設置為0。不過它可以轉換成 java8 中的 LocalDate類。

java.sql.Date now = new java.sql.Date(100000000);
System.out.println(now);
//結果:1970-01-02

LocalDate date4 = now.toLocalDate();
System.out.println(date4);

java.sql.Time 對應SQL中的 TIME類型

java.sql.Time nowTime = new java.sql.Time(1000000000);
System.out.println(nowTime);
//結果:21:46:40

java.sql.Timestamp sql時間戳,對應於SQL中的TIMESTAMP類,精確到納秒級

java.sql.Timestamp nowTimestamp = new java.sql.Timestamp(1000000000);
System.out.println(nowTimestamp);
//結果:1970-01-12 21:46:40.0

1.3 java.util.Calendar

java.util.Calendar是一個抽象類,能夠存儲 年月日時分秒,同時實現加減乘除。但是其主要作用於包含豐富靈活的方法實現對日期,包括年、月、日和星期的互相轉換,比如想知道某年某月最後一天的日期是多少,以及今年有多少周。

BTW:在Calendar中,一周從 SUNDAY 開始到 SATURDAY 結束是1~7,一年月份是從Jan 到 Dec 對應 0~11。

具體可以參考 申城異鄉人-Java Calendar類使用總結

Calendar calendar = Calendar.getInstance();
Date nowDate = calendar.getTime();
//// or
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH)+1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
// 24小時制
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);

​ 在Java 1.8之後提供了三個新的時間類,localDate localTime localDateTime 分別對應日期,時間,日期+時間,三者都是final修飾,不可變類,因此線程安全。

2.1 java.time.LocalDate

localDate 保存日期,可以獲取日期對應的星期,因此可以用於打印日曆,參考SleeypbearZz-Java通過LocalDate類打印當前月日曆。它提供了比上面更多的方法,以下列舉了一些,完整參考api文檔。

// 構造
LocalDate nowLocalDate = LocalDate.now();
LocalDate toDay = LocalDate.of(2021,8,15);
System.out.println("LocalDate默認時間格式是: " + nowLD);
System.out.println(nowLD.getDayOfWeek() + " + " + nowLD.getMonthValue() + " + " + + nowLD.getDayOfYear());

//設置,其他不變,只改變對應的月,年。
System.out.println(nowLD.withMonth(2) + " + " +  nowLD.withYear(2019));
// 增加
System.out.println(nowLD.plusDays(1) + " + " + nowLD.plusWeeks(1) + " + " + nowLD.plusMonths(1) + " + " + nowLD.plusYears(1));
//減少
System.out.println(nowLD.minusDays(1) + " + " + nowLD.minusWeeks(1) + " + " + nowLD.minusMonths(1) + " + " + nowLD.minusYears(1));
//還提供了計算兩個時間點的時間差 until相關方法,複雜了一些,以後有時間再研究

2.2 java.time.localTime

localTime 參考文章 ZetCode-Java LocalTime。總結有一下的內容:

LocalTime 只保存時間,精確到納秒,基本上LocalDate有的,它也都有,同時它的 until()方法使用簡單,用於計算兩個時間點之間的時間差,但是要切忌隔天計算。

LocalTime nowLocalTime = LocalTime.now();
System.out.println("LocalTime默認時間格式是: " + nowLocalTime);
// 結果是 「LocalTime默認時間格式是: 17:50:24.438」

LocalTime t1 = LocalTime.of(8,20);
LocalTime t2 = LocalTime.of(17, 20, 45, 342123342);
LocalTime t3 = LocalTime.parse("08:20",DateTimeFormatter.ISO_TIME);
LocalTime t4 = LocalDateTime.now().toLocalTime();

LocalTime t5 = t1.plusMinutes(1).plusHours(40);
System.out.println(t5.until(t1, MINUTES));
System.out.println(MINUTES.between(t1, t5) + " + " + t5.until(t1,HOURS) + " + " + t5.until(t1,HALF_DAYS));    

2.3 java.time.LocalDateTime

最後是 LocalDateTime 集合了上述兩個的特性,包含了幾乎全部的方法,以及向 LocalDate和 LocalTime的轉換,在此就不再贅述,可以根據自己需要仔細研究,感覺你想要的,想不到的方法都具備。

總結

推薦使用Java8 Java.time.Local前綴 的時間類,原因有:

  1. 提供了更多靈活好用的API;
  2. 新版日期類庫都是不可變類且線程安全。

參考:

  1. Java時間類總結
  2. SleeypbearZz-Java通過LocalDate類打印當前月日曆
  3. 申城異鄉人-Java Calendar類使用總結
  4. ZetCode-Java LocalTime
  5. Java8官方文檔
Tags: