JDK8 新增的日期時間類
在本人之前的博文《處理時間的類 —— System類、Date類 、SimpleDateFormat類 與 Calendar類》中,講到過表示時間的類,有三類:Date、SimpleDateFormat、Calendar類(System.currentTimeMillis()勉強也能算作是一個)
那么,在JDK8的時代,Java提供了幾個新的、線程安全的、用於處理時間的類。
現在,本人就來講講這幾個類:
@
首先是 LocalDate、LocalTime、LocalDateTime類:
LocalDate、LocalTime、LocalDateTime類:
概述:
這三個類分別表示使用 ISO-8601日歷系統的 日期、時間、日期和時間
它們提供了簡單的日期或時間,並不包含 當前的時間 信息。
也不包含 與時區相關 的信息。
注: ISO-8601日歷系統 是 國際標准化組織制定的現代公民的日期和時間的表示法
這些新增的日期時間API都在 java.time包下
獲取對象的方法:
獲取對象的方法:
- 通過靜態方法 :now()(獲取的時間是系統當前的時間)
- 通過靜態方法:of()(方法參數可以指定時間)
那么,現在,本人來通過代碼來展示下如何去 獲取對象:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class Test {
public static void main(String[] args) {
/* 通過靜態方法 now() 返回該類的實例 */
//獲取當前的日期時分秒
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
//獲取當前的日期
LocalDate now1 = LocalDate.now();
System.out.println(now1);
//獲取當前的時分秒
LocalTime now2 = LocalTime.now();
System.out.println(now2);
System.out.println("=========================================");
/* 靜態方法 of() 返回該類的實例 */
//指定日期時分秒
LocalDateTime localDateTime = LocalDateTime.of(2048, 11, 25, 12, 00, 30);
System.out.println(localDateTime);
//指定日期
LocalDate date = LocalDate.of(2020, 12, 12);
System.out.println(date);
//指定時分秒
LocalTime time = LocalTime.of(14, 20, 30);
System.out.println(time);
}
}
那么,現在,本人來展示下運行結果:

常用方法:
與獲取相關的方法(get系類的方法):
- getYear():
獲取年- ldt.getHour():
獲取小時- getMinute():
獲取分鍾- getSecond():
獲取秒值- getDayOfMonth():
獲得月份天數(1-31)- getDayOfYear():
獲得年份天數(1-366)- getDayOfWeek():
獲得星期幾(返回一個 DayOfWeek枚舉值)- getMonth():
獲得月份(返回一個 Month 枚舉值)- getMonthValue():
獲得月份(1-12)- getYear():
獲得年份
那么,現在,本人來通過代碼來展示下與獲取相關的方法 的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.LocalDateTime;
import java.time.Month;
public class Test {
public static void main(String[] args) {
//獲取日期時分秒
LocalDateTime now = LocalDateTime.now();
//獲取年份
int year = now.getYear();
System.out.println(year);
//獲取月份枚舉
//Month 枚舉類,定義了十二個月份
Month month = now.getMonth();
System.out.println(month);
//獲取月份的數值
int monthValue = now.getMonthValue();
System.out.println(monthValue);
//獲取當天在本月的第幾天
int dayOfMonth = now.getDayOfMonth();
System.out.println(dayOfMonth);
//獲取小時
int hour = now.getHour();
System.out.println(hour);
//獲取分鍾
int minute = now.getMinute();
System.out.println(minute);
//獲取秒值
int second = now.getSecond();
System.out.println(second);
}
}
那么,現在,本人來展示下運行結果:

格式化日期日期字符串的方法:
- format():
格式化字符串
那么,現在,本人來通過代碼來展示下如何去 格式化日期日期字符串:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Test {
public static void main(String[] args) {
//獲取當前日期時分秒
LocalDateTime now = LocalDateTime.now();
//默認格式 年-月-日T時:分:秒
System.out.println(now);
//指定格式
DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy年MM月DD日 HH時mm分ss秒");
//傳入格式
String dateStr = now.format(ofPattern);
System.out.println(dateStr);
}
}
那么,現在,本人來展示下運行結果:

轉換的方法:
- toLocalDate():
將目標LocalDateTime轉換為相應的LocalDate對象- toLocalTime():
將目標LocalDateTime轉換為相應的LocalTime對象
那么,現在,本人來通過代碼來展示下如何去 轉換:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class Test {
public static void main(String[] args) {
//獲取當前年月日,時分秒
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
//將目標LocalDateTime轉換為相應的LocalDate對象
LocalDate localDate = now.toLocalDate();
System.out.println(localDate);
///將目標LocalDateTime轉換為相應的LocalTime對象
LocalTime localTime = now.toLocalTime();
System.out.println(localTime);
}
}
那么,現在,本人來展示下運行結果:

判斷的方法:
- isAfter():
判斷一個日期是否在指定日期之后- isBefore():
判斷一個日期是否在指定日期之前- isEqual():
判斷兩個日期是否相同- isLeapYear():
判斷是否是閏年(注意是LocalDate類 和 LocalDateTime類特有的方法)
那么,現在,本人來通過代碼來展示下這些API的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.LocalDate;
public class Test {
public static void main(String[] args) {
//獲取當前的日期
LocalDate now = LocalDate.now();
//指定的日期
LocalDate of = LocalDate.of(2015, 12, 12);
//判斷一個日期是否在另一個日期之前
boolean before = of.isBefore(now);
System.out.println(before);
//判斷一個日期是否在另一個日期之后
boolean after = of.isAfter(now);
System.out.println(after);
//判斷這兩個日期是否相等
boolean after1 = now.equals(of);
System.out.println(after1);
//判斷閏年
boolean leapYear = of.isLeapYear();
System.out.println(leapYear);
}
}
那么,現在,本人來展示下運行結果:

解析字符串的方法:
- paser(String str):
將一個日期字符串解析成日期對象,注意字符串日期的寫法的格式要正確,否則解析失敗- paser(String str, DateTimeFormatter formatter):
將字符串按照參數傳入的格式進行解析
那么,現在,本人來通過代碼來展示下如何去 解析字符串:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class Test {
public static void main(String[] args) {
//給出一個符合默認格式要求的日期字符串
String dateStr="2020-01-01";
//把日期字符串解析成日期對象 如果日期字符串時年月日 解析時用 LocalDate
LocalDate parse = LocalDate.parse(dateStr);
System.out.println(parse);
System.out.println("===========================================");
//給出一個符合默認格式要求的 時分秒 字符串
String dateTimeStr="14:20:30";
//把 時分秒 字符串解析成時分秒對象
LocalTime parse1 = LocalTime.parse(dateTimeStr);
System.out.println(parse1);
System.out.println("=========================================");
//給出一個符合默認格式要求的 日期時分秒 字符串
String str="2018-12-12T14:20:30";
//把 日期時分秒 字符串解析成時分秒對象
LocalDateTime parse2 = LocalDateTime.parse(str);
System.out.println(parse2);
System.out.println("========================================");
//給出一個自定義日期時分秒格式字符串
String dateStr2="2020年12月12日 12:13:14";
//給出一個自定義解析格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
//按照指定的格式去解析
LocalDateTime parse3 = LocalDateTime.parse(dateStr2,formatter);
System.out.println(parse3);
}
}
那么,現在,本人來展示下運行結果:

增減年月日時分秒的方法(plus/minus系列的方法):
- plusYears(int offset):
增加指定年份- plusMonths(int offset):
增加指定月份- plusWeeks(int offset):
增加指定周- plusDates(int offset):
增加指定日- plusHours(int offset):
增加指定時- plusMinuets(int offset):
增加指定分- plusSeconds(int offset):
增加指定秒- plusNanos(int offset):
增加指定納秒
- minusYears(int offset):
減少指定年- minusMonths(int offset):
減少指定月- minusWeeks(int offset):
減少指定周- minusDates(int offset):
減少指定日- minusHours(int offset):
減少指定時- minusMinuets(int offset):
減少指定分- minusSeconds(int offset):
減少指定秒- minusNanos(int offset):
減少指定納秒
那么,現在,本人來通過代碼來展示下部分API的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class Test {
public static void main(String[] args) {
//增加時間量的方法 plusXXX系類的方法 返回的是一個新的日期對象
LocalDateTime now = LocalDateTime.now();
//可以給當前的日期增加時間量
LocalDateTime newDate= now.plusYears(1);
int year = newDate.getYear();
System.out.println(year);
System.out.println("================================");
//減去時間量的方法minusXXX 系列的方法 返回的是一個新的日期對象
LocalDate now1 = LocalDate.now();
LocalDate newDate2 = now1.minusDays(10);
int dayOfMonth = newDate2.getDayOfMonth();
System.out.println(dayOfMonth);
}
}
那么,現在,本人來展示下運行結果:

指定年月日時分秒的方法:
- with(TemporalAdjuster adjuster):
指定特殊時間- withYear(int year):
指定年- withDayOfYear(int dayOfYear):
指定日- withMonth(int month):
指定月- withDayOfMonth(int dayOfMonth):
指定日
那么,現在,本人來通過代碼來展示下部分API的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
public class Test {
public static void main(String[] args) {
//指定某個日期的方法 with()方法
LocalDate now2 = LocalDate.now();
LocalDate localDate = now2.withYear(2014);
System.out.println(localDate);
// TemporalAdjusters工具類,提供了一些獲取特殊日期的方法
LocalDate with = now2.with(TemporalAdjusters.firstDayOfMonth());
System.out.println(with);
LocalDate with1 = now2.with(TemporalAdjusters.firstDayOfNextMonth());
System.out.println(with1);
//獲取這個月的第幾個星期幾是幾號,比如 TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY)
// 代表的意思是這個月的第二個星期五是幾號
LocalDate with2 = now2.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY));
System.out.println(with2);
}
}
那么,現在,本人來展示下運行結果:

在上文中,本人運用到了TemporalAdjuster接口,
那么,現在,本人就來講解下這個接口:
TemporalAdjuster接口 —— 時間校正器:
概述:
一般我們用該接口的一個對應的工具類 TemporalAdjusters中的一些常量,
來指定日期
對於這個接口,我們主要運用它的幾個常量 和 next()方法來指定日期
或者采用自定義的方式來指定日期
現在,本人來通過一段代碼來展示下這個接口的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
public class Test {
public static void main(String[] args) {
LocalDate now = LocalDate.now();
//指定日期
//對於一些特殊的日期,可以通過一個工具類TemporalAdjusters 來指定
TemporalAdjuster temporalAdjuster = TemporalAdjusters.firstDayOfMonth(); //見名知意,本月第一天
LocalDate with = now.with(temporalAdjuster);
System.out.println(with);
TemporalAdjuster next = TemporalAdjusters.next(DayOfWeek.SUNDAY); //下周周末
LocalDate with1 = now.with(next);
System.out.println(with1);
System.out.println("===================================");
LocalDate now1 = LocalDate.now();
//自定義日期 —— 下一個工作日
LocalDate with2 = now1.with(new TemporalAdjuster() {
@Override
//參數 nowDate 當前的日期對象
public Temporal adjustInto(Temporal nowDate) {
//向下轉型
LocalDate date= (LocalDate) nowDate;
if(date.getDayOfWeek().equals(DayOfWeek.FRIDAY)){
LocalDate localDate = date.plusDays(3);
return localDate;
}else if(date.getDayOfWeek().equals(DayOfWeek.SATURDAY)){
LocalDate localDate = date.plusDays(2);
return localDate;
}else{
LocalDate localDate = date.plusDays(1);
return localDate;
}
}
});
System.out.println("下一個工作日是:" + with2);
}
}
那么,現在,本人來展示下運行結果:

Instant 時間戳類:
獲取對象的方法:
now():
注意默認獲取出來的是當前的美國時間,
和我們相差八個小時(因為我們在東八時區)
設置偏移量的方法:
atOffset():
獲取系統默認時區時間的方法:
atZone():
方法的參數是要一個時區的編號(可以通過時區編號類獲取ZonedDateTime類的對象)
get系列的方法:
- getEpochSecond():
獲取從1970-01-01 00:00:00到當前時間的秒值- toEpochMilli():
獲取從1970-01-01 00:00:00到當前時間的毫秒值- getNano():
把獲取到的當前時間的秒數 換算成納秒
ofEpoch系列方法:
- ofEpochSecond():
給計算機元年增加秒數- ofEpochMilli():
給計算機元年增加毫秒數
現在,本人來展示下這些API的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Date;
public class Test {
public static void main(String[] args) {
// Instant 時間戳類從1970 -01 - 01 00:00:00 截止到當前時間的毫秒值
Instant now = Instant.now();
System.out.println(now); //獲取的是默認時區,獲取的不是中國 的時區
//獲取當前時區的,我們可以添加偏移量,返回偏移過后的日期
OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);
System.out.println("===========================");
//從1970 - 01 - 01 00:00:00 截止到當前時間的毫秒值
long l = System.currentTimeMillis();
System.out.println(l);
long time = new Date().getTime();
//JDK1.8 Instant 時間戳類從1970 -01 - 01 00:00:00 截止到當前時間的毫秒值
Instant now1 = Instant.now();
//toEpochMilli():從1970 -01 - 01 00:00:00 截止到當前時間間隔的毫秒值
long l1 = now1.toEpochMilli();
System.out.println(l1);
//獲取從1970 -01 - 01 00:00:00 截止到當前時間間隔的秒值
long epochSecond = now1.getEpochSecond();
System.out.println(epochSecond);
System.out.println("==========================");
//給計算機元年增加相應的時間量
Date date = new Date(1000 * 60 * 60*24);
System.out.println(date);
//現在 給計算機元年增加相應的時間量
//5. ofEpochSecond() 方法 給計算機元年增加秒數
//ofEpochMilli() 給計算機元年增加毫秒數
Instant instant = Instant.ofEpochMilli(1000 * 60 * 60 * 24);
System.out.println(instant);
//ofEpochSecond() 方法 給計算機元年增加秒數
Instant instant1 = Instant.ofEpochSecond(60 * 60 * 24);
System.out.println(instant1);
}
}
那么,現在本人來展示下運行結果:

Duration類 —— 用於計算兩個“時間”間隔的類:
常用API:
- 靜態方法 between():
計算兩個時間的間隔,默認是秒- toDays():
將時間轉換為以天為單位的- toHours():
將時間轉換為以時為單位的- toMinutes():
將時間轉換為以分鍾為單位的- toMillis():
將時間轉換為以毫秒為單位的- toNanos():
將時間轉換為以納秒為單位的
那么,現在本人來通過一段代碼展示下這些API的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.Duration;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Date;
public class Test {
public static void main(String[] args) {
//計算時間的間隔
Instant start = Instant.now();
for (int i = 0; i < 15; i++) {
System.out.println(i);
}
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
long l = duration.toNanos();
//間隔的時間
System.out.println("循環耗時:"+l+"納秒");
}
}
現在,本人來展示下運行結果:

Period類 —— 用於計算兩個“日期”間隔的類:
- 靜態方法 between():
計算兩個日期之間的間隔- getYears():
獲取年份- getMonths():
獲取月份- getDays():
獲取天數
那么,現在本人來通過一段代碼展示下這些API的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.*;
public class Test {
public static void main(String[] args) {
//計算兩個日期的間隔
LocalDate birthday = LocalDate.of(2012, 12, 12);
LocalDate now = LocalDate.now();
//我從出生到現在,有多少歲,零幾個月,幾天
//計算兩個日期的間隔
Period between = Period.between(birthday, now);
int years = between.getYears();
int months = between.getMonths();
int days = between.getDays();
System.out.println("瑪雅人的地球都消滅了"+years+"年"+months+"月"+days+"天了...");
}
}
那么,現在,本人來展示下運行結果:

DateTimeFormatter類 —— 解析和格式化日期或時間的類
本人現在來展示下這個類的常用API :
- 靜態方法ofPattern("yyyy-MM-dd"):
通過給定格式獲取對象- format():
把一個日期對象的默認格式 格式化成指定的格式的字符串
那么,現在,本人來展示下這個類的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
public class Test {
public static void main(String[] args) {
// 之前格式化日期的類 new SimpleDateFormat()
//JDK1.8 DateTimeFormatter
//指定格式 靜態方法 ofPattern()
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// DateTimeFormatter 自帶的格式方法
LocalDateTime now = LocalDateTime.now();
//把日期對象,格式化成字符串
String format = formatter.format(now);
//剛才的方式是使用的日期自帶的格式化方法
String format1 = now.format(formatter);
System.out.println(format);
System.out.println(format1);
}
}
那么,現在本人來展示下運行結果:

ZonedDate、ZonedTime、ZonedDateTime —— 帶時區的時間或日期
概述:
這個三個類方法及用法和 LocalDate、 LocalTime、 LocalDateTime 基本一樣
只不過ZonedDate,ZonedTime、ZonedDateTime 這三個帶有當前系統的默認時區的時間表示類
那么使用這三個類,就不得不介紹下 ZoneID類:
ZoneID —— 世界時區類:
常用API:
- getAvailableZoneIds():
.獲取世界各個地方的時區的集合- systemDefault():
獲取系統默認時區的ID- of(String zoneName):
根據各個地區的時區ID名創建對象
那么,現在,本人就來展示下這幾個類的使用:
package edu.youzg.about_new_features.core.about_jdk8.core;
import java.time.*;
import java.util.Set;
public class Test {
public static void main(String[] args) {
//ZoneID 世界時區類
//獲取世界各地的時區編號。
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
for (String availableZoneId : availableZoneIds) {
System.out.println(availableZoneId);
}
System.out.println("=====================");
//獲取系統的默認時區編號
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);
//獲取其他國家的日期
LocalDateTime now = LocalDateTime.now();
//獲取指定時區的日期時間
ZoneId zoneId1 = ZoneId.of("Europe/Monaco");
ZonedDateTime zonedDateTime = now.atZone(zoneId1); //獲得指定時區的當前時間
System.out.println(zonedDateTime);
System.out.println("=====================");
//根據時區,獲取該地區的日期
LocalDateTime now1 = LocalDateTime.now(ZoneId.of("America/Phoenix")); //獲得指定時區的當前時間(不帶時區信息)
System.out.println(now1);
}
}
由於世界各地的時區編號太多,所以,本人僅展示最后的幾個輸出結果:

