1. 程式人生 > >Java8 日期和時間實用技巧

Java8 日期和時間實用技巧

ron 定義 com 閏年 上下 代碼 添加 sta date

新的日期API

  • ZoneId: 時區ID,用來確定Instant和LocalDateTime互相轉換的規則
  • Instant: 用來表示時間線上的一個點
  • LocalDate: 表示沒有時區的日期, LocalDate是不可變並且線程安全的
  • LocalTime: 表示沒有時區的時間, LocalTime是不可變並且線程安全的
  • LocalDateTime: 表示沒有時區的日期時間, LocalDateTime是不可變並且線程安全的
  • Clock: 用於訪問當前時刻、日期、時間,用到時區
  • Duration: 用秒和納秒表示時間的數量

最常用的就是LocalDate、LocalTime、LocalDateTime,從它們的名字就可以看出是操作日期和時間的。

這些類是主要用於當時區不需要顯式地指定的上下文。在本章節中我們將討論最常用的api。

LocalDate

LocalDate代表一個IOS格式(yyyy-MM-dd)的日期,可以存儲 生日、紀念日等日期。
獲取當前的日期:

LocalDate localDate = LocalDate.now();
System.out.println("localDate: " + localDate);

輸出

技術分享

LocalDate可以指定特定的日期,調用of或parse方法返回該實例:

LocalDate.of(2017, 07, 27);
LocalDate.parse("2017-07-27");

當然它還有一些其他方法,我們一起來看看:

//為今天添加一天,也就是獲取明天

LocalDate tomorrow = LocalDate.now().plusDays(1);

//從今天減去一個月

LocalDate prevMonth = LocalDate.now().minus(1, ChronoUnit.MONTHS);

輸出

技術分享

下面寫兩個例子,分別解析日期 2017-07-27,獲取每周中的星期和每月中的日:

DayOfWeek thursday = LocalDate.parse("2017-07-27").getDayOfWeek();
System.out.println("周四: " + thursday);
int twenty = LocalDate.parse("2017-07-27").getDayOfMonth();
System.out.println("twenty: " + twenty);

輸出

技術分享

試試今年是不是閏年:

boolean leapYear = LocalDate.now().isLeapYear();
System.out.println("是否閏年: " + leapYear);

輸出

技術分享

判斷是否在日期之前或之後:

boolean notBefore = LocalDate.parse("2017-07-27")
                .isBefore(LocalDate.parse("2017-07-29"));
System.out.println("notBefore: " + notBefore);
boolean isAfter = LocalDate.parse("2017-07-27").isAfter(LocalDate.parse("2017-07-29"));
System.out.println("isAfter: " + isAfter);

輸出

技術分享

獲取這個月的第一天:

LocalDate firstDayOfMonth = LocalDate.parse("2017-07-27")
                .with(TemporalAdjusters.firstDayOfMonth());
System.out.println("這個月的第一天: " + firstDayOfMonth);
firstDayOfMonth = firstDayOfMonth.withDayOfMonth(1);
System.out.println("這個月的第一天: " + firstDayOfMonth);

輸出

技術分享

判斷今天是否是我的生日,例如我的生日是 2017-07-27

LocalDate birthday = LocalDate.of(2017, 07, 27);
MonthDay birthdayMd = MonthDay.of(birthday.getMonth(), birthday.getDayOfMonth());
MonthDay today = MonthDay.from(LocalDate.now());
System.out.println("今天是否是我的生日: " + today.equals(birthdayMd));

輸出

技術分享

LocalTime

LocalTime表示一個時間,而不是日期,下面介紹一下它的使用方法。

獲取現在的時間

LocalTime now = LocalTime.now();
System.out.println("現在的時間: " + now);

輸出

技術分享

將一個字符串時間解析為LocalTime

LocalTime nowTime = LocalTime.parse("14:18");
System.out.println("時間是: " + nowTime);

輸出

技術分享

使用靜態方法of創建一個時間

LocalTime nowTime = LocalTime.of(14, 18);
System.out.println("時間是: " + nowTime);

使用解析字符串的方式並添加一小時

LocalTime nextHour = LocalTime.parse("14:18").plus(1, ChronoUnit.HOURS);
System.out.println("下一個小時: " + nextHour);

輸出

技術分享

獲取時間的小時、分鐘

int hour = LocalTime.parse("14:18").getHour();
System.out.println("小時: " + hour);
int minute = LocalTime.parse("14:18").getMinute();
System.out.println("分鐘: " + minute);

輸出

技術分享

我們也可以通過之前類似的API檢查一個時間是否在另一個時間之前、之後

boolean isBefore = LocalTime.parse("14:18").isBefore(LocalTime.parse("15:18"));
boolean isAfter = LocalTime.parse("14:18").isAfter(LocalTime.parse("15:18"));
System.out.println("isBefore: " + isBefore);
System.out.println("isAfter: " + isAfter);

輸出

技術分享

在LocalTime類中也將每天的開始和結束作為常量供我們使用:

System.out.println(LocalTime.MAX);
System.out.println(LocalTime.MIN);

輸出:

技術分享

LocalDateTime

LocalDateTime是用來表示日期和時間的,這是一個最常用的類之一。

獲取當前的日期和時間:

LocalDateTime now = LocalDateTime.now();
System.out.println("現在: " + now);

輸出

技術分享

下面使用靜態方法和字符串的方式分別創建 LocalDateTime 對象

LocalDateTime now = LocalDateTime.now();
LocalDateTime.of(2017, Month.JULY, 20, 15, 18); LocalDateTime.parse("2017-07-20T15:18:00"); //同時`LocalDateTime`也提供了相關API來對日期和時間進行增減操作: LocalDateTime tomorrow = now.plusDays(1); System.out.println("明天的這個時間: " + tomorrow); LocalDateTime minusTowHour = now.minusHours(2); System.out.println("兩小時前: " + minusTowHour);

輸出

技術分享

這個類也提供一系列的get方法來獲取特定單位:

LocalDateTime now = LocalDateTime.now();
Month month = now.getMonth(); System.out.println("當前月份: " + month);

輸出

技術分享

日期格式化

在日常開發中我們用到最多的也許就是日期、時間的格式化了,那在Java8種該如何操作

LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println("默認格式化: " + now);
System.out.println("自定義格式化: " + now.format(dateTimeFormatter));
LocalDateTime localDateTime = LocalDateTime.parse("2017-07-27 14:53:40", dateTimeFormatter);
System.out.println("字符串轉LocalDateTime: " + localDateTime);

輸出

技術分享

也可以使用DateTimeFormatterformat方法將日期、時間格式化為字符串

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String dateString = dateTimeFormatter.format(LocalDate.now());
System.out.println("日期轉字符串: " + dateString);

輸出

技術分享

日期周期

Period類用於修改給定日期或獲得的兩個日期之間的區別。

給初始化的日期添加5天:

LocalDate initialDate = LocalDate.parse("2017-07-27");
LocalDate finalDate   = initialDate.plus(Period.ofDays(5));
System.out.println("初始化日期: " + initialDate);
System.out.println("加日期之後: " + finalDate);

//周期API中提供給我們可以比較兩個日期的差別,像下面這樣獲取差距天數:
long between = ChronoUnit.DAYS.between(initialDate, finalDate); System.out.println("差距天數: " + between);

上面的代碼會返回5,當然你想獲取兩個日期相差多少小時也是簡單的。

輸出

技術分享

與遺留代碼轉換

在之前的代碼中你可能出現了大量的Date類,如何將它轉換為Java8種的時間類

DateInstant互相轉換

Date date = Date.from(Instant.now());
Instant instant = date.toInstant();

Date轉換為LocalDateTime

LocalDateTime localDateTime = LocalDateTime.from(new Date());
System.out.println(localDateTime);

LocalDateTimeDate

Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

LocalDateDate

Date date = Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

Java8 日期和時間實用技巧