jdk 1.8
以前, Java
時間使用java.util.Date
和 java.util.Calendar
類。java
Date today = new Date(); System.out.println(today); // 轉爲字符串 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String todayStr = sdf.format(today); System.out.println(todayStr);
Date
的幾個問題:git
Date
打印出的日期可讀性差;SimpleDateFormat
對時間進行格式化,但 SimpleDateFormat
是線程不安全的(阿里巴巴開發手冊中禁用static
修飾SimpleDateFormat
);Date
對時間處理比較麻煩,好比想獲取某年、某月、某星期,以及 n
天之後的時間,若是用Date
來處理的話真是太難了,而且 Date
類的 getYear()
、getMonth()
這些方法都被棄用了;JDK 1.8
新的日期時間類型
Java8
引入的新的一系列API
,對時間日期的處理提供了更好的支持,清楚的定義了時間日期的一些概念,好比說,瞬時時間(Instant
),持續時間(duration
),日期(date
),時間(time
),時區(time-zone
)以及時間段(Period
)。github
LocalDate
:不包含時間的日期,好比2019-10-14
。能夠用來存儲生日,週年記念日,入職日期等。LocalTime
:與LocalDate
想對照,它是不包含日期的時間。LocalDateTime
:包含了日期及時間,沒有偏移信息(時區)。ZonedDateTime
:包含時區的完整的日期時間,偏移量是以UTC
/格林威治時間爲基準的。Instant
:時間戳,與System.currentTimeMillis()
相似。Duration
:表示一個時間段。Period
:用來表示以年月日來衡量一個時間段。DateTimeFormatter
:新的日期解析格式化類。LocalDate
LocalDate
類內只包含日期,不包含具體時間。只須要表示日期而不包含時間,就可使用它。安全
public static void localDate() { //獲取當前年月日 LocalDate today = LocalDate.now(); System.out.println("當前年月日:" + today); // 獲取年的兩種方式 int thisYear = today.getYear(); int thisYearAnother = today.get(ChronoField.YEAR); System.out.println("今年是" + thisYear + "年"); System.out.println("今年是" + thisYearAnother + "年"); // 獲取月 Month thisMonth = today.getMonth(); System.out.println(thisMonth.toString()); // 這是今年的第幾個月(兩種寫法) int monthOfYear = today.getMonthValue(); // int monthOfYear = today.get(ChronoField.MONTH_OF_YEAR); System.out.println("這個月是今年的第" + monthOfYear + "個月"); // 月份的天數 int length = today.lengthOfMonth(); System.out.println("這個月有" + length + "天"); // 獲取日的兩種方式 int thisDay = today.getDayOfMonth(); int thisDayAnother = today.get(ChronoField.DAY_OF_MONTH); System.out.println("今天是這個月的第" + thisDay + "天"); System.out.println("今天是這個月的第" + thisDayAnother + "天"); // 獲取星期 DayOfWeek thisDayOfWeek = today.getDayOfWeek(); System.out.println(thisDayOfWeek.toString()); // 今天是這周的第幾天 int dayOfWeek = today.get(ChronoField.DAY_OF_WEEK); System.out.println("今天是這周的第" + dayOfWeek + "天"); // 是否爲閏年 boolean leapYear = today.isLeapYear(); System.out.println("今年是閏年:" + leapYear); //構造指定的年月日 LocalDate anotherDay = LocalDate.of(2008, 8, 8); System.out.println("指定年月日:" + anotherDay); }
LocalTime
LocalTime
只會獲取時間,不獲取日期。LocalTime
和LocalDate
相似,區別在於LocalDate不包含具體時間,而LocalTime
不包含具體日期。工具
public static void localTime() { // 獲取當前時間 LocalTime nowTime = LocalTime.now(); System.out.println("當前時間:" + nowTime); //獲取小時的兩種方式 int hour = nowTime.getHour(); int thisHour = nowTime.get(ChronoField.HOUR_OF_DAY); System.out.println("當前時:" + hour); System.out.println("當前時:" + thisHour); //獲取分的兩種方式 int minute = nowTime.getMinute(); int thisMinute = nowTime.get(ChronoField.MINUTE_OF_HOUR); System.out.println("當前分:" + minute); System.out.println("當前分:" + thisMinute); //獲取秒的兩種方式 int second = nowTime.getSecond(); int thisSecond = nowTime.get(ChronoField.SECOND_OF_MINUTE); System.out.println("當前秒:" + second); System.out.println("當前秒:" + thisSecond); // 構造指定時間(最多可到納秒) LocalTime anotherTime = LocalTime.of(20, 8, 8); System.out.println("構造指定時間:" + anotherTime); }
LocalDateTime
LocalDateTime
表示日期和時間組合。能夠經過of()方法直接建立,也能夠調用LocalDate
的atTime()
方法或LocalTime
的atDate()
方法將LocalDate
或LocalTime
合併成一個LocalDateTime
。post
public static void localDateTime() { // 當前日期和時間 LocalDateTime today = LocalDateTime.now(); System.out.println("如今是:" + today); // 建立指定日期和時間 LocalDateTime anotherDay = LocalDateTime.of(2008, Month.AUGUST, 8, 8, 8, 8); System.out.println("建立的指定時間是:" + anotherDay); // 拼接日期和時間 // 使用當前日期,指定時間生成的 LocalDateTime LocalDateTime thisTime = LocalTime.now().atDate(LocalDate.of(2008, 8, 8)); System.out.println("拼接的日期是:" + thisTime); // 使用當前日期,指定時間生成的 LocalDateTime LocalDateTime thisDay = LocalDate.now().atTime(LocalTime.of(12, 24, 12)); System.out.println("拼接的日期是:" + thisDay); // 指定日期和時間生成 LocalDateTime LocalDateTime thisDayAndTime = LocalDateTime.of(LocalDate.of(2008, 8, 8), LocalTime.of(12, 24, 12)); System.out.println("拼接的日期是:" + thisDayAndTime); // 獲取LocalDate LocalDate todayDate = today.toLocalDate(); System.out.println("今天日期是:" + todayDate); // 獲取LocalTime LocalTime todayTime = today.toLocalTime(); System.out.println("如今時間是:" + todayTime); }
Instant
Instant
用於一個獲取時間戳,與System.currentTimeMillis()
相似,但Instant
能夠精確到納秒。this
public class InstantDemo { public static void main(String[] args) { // 建立Instant對象 Instant instant = Instant.now(); // 經過ofEpochSecond方法建立(第一個參數表示秒,第二個參數表示納秒) Instant another = Instant.ofEpochSecond(365 * 24 * 60, 100); // 獲取到秒數 long currentSecond = instant.getEpochSecond(); System.out.println("獲取到秒數:" + currentSecond); // 獲取到毫秒數 long currentMilli = instant.toEpochMilli(); System.out.println("獲取到毫秒數:" + currentMilli); } }
Duration
Duration
的內部實現與Instant
相似,但Duration
表示時間段,經過between
方法建立,還能夠經過of()
方法建立。線程
public static void duration() { LocalDateTime from = LocalDateTime.now(); LocalDateTime to = LocalDateTime.now().plusDays(1); // 經過between()方法建立 Duration duration = Duration.between(from, to); // 經過of()方法建立,該方法參數爲時間段長度和時間單位。 // 7天 Duration duration1 = Duration.of(7, ChronoUnit.DAYS); // 60秒 Duration duration2 = Duration.of(60, ChronoUnit.SECONDS); }
Period
Period
與Duration
相似,獲取一個時間段,只不過單位爲年月日,也能夠經過of
方法和between
方法建立,between
方法接收的參數爲LocalDate
。code
private static void period() { // 經過of方法 Period period = Period.of(2012, 12, 24); // 經過between方法 Period period1 = Period.between(LocalDate.now(), LocalDate.of(2020,12,31)); }
isBefore()
和isAfter()
判斷給定的時間或日期是在另外一個時間/日期以前仍是以後。
以LocalDate
爲例,LocalDateTime
/LocalTime
同理。orm
public static void compare() { LocalDate thisDay = LocalDate.of(2008, 8, 8); LocalDate otherDay = LocalDate.of(2018, 8, 8); // 晚於 boolean isAfter = thisDay.isAfter(otherDay); System.out.println(isAfter); // 早於 boolean isBefore = thisDay.isBefore(otherDay); System.out.println(isBefore); }
以
LocalDateTime
爲例,LocalDate
/LocalTime
同理。
public static void plusAndMinus() { // 增長 LocalDateTime today = LocalDateTime.now(); LocalDateTime nextYearDay = today.plusYears(1); System.out.println("下一年的今天是:" + nextYearDay); LocalDateTime nextMonthDay = today.plus(1, ChronoUnit.MONTHS); System.out.println("下一個月的今天是:" + nextMonthDay); //減小 LocalDateTime lastMonthDay = today.minusMonths(1); LocalDateTime lastYearDay = today.minus(1, ChronoUnit.YEARS); System.out.println("一個月前是:" + lastMonthDay); System.out.println("一年前是:" + lastYearDay); }
經過
with
修改時間
public static void edit() { LocalDateTime today = LocalDateTime.now(); // 修改年爲2012年 LocalDateTime thisYearDay = today.withYear(2012); System.out.println("修改年後的時間爲:" + thisYearDay); // 修改成12月 LocalDateTime thisMonthDay = today.with(ChronoField.MONTH_OF_YEAR, 12); System.out.println("修改月後的時間爲:" + thisMonthDay); }
經過
TemporalAdjusters
的靜態方法 和Duration
計算時間
public static void compute() { // TemporalAdjusters 的靜態方法 LocalDate today = LocalDate.now(); // 獲取今年的第一天 LocalDate date = today.with(firstDayOfYear()); System.out.println("今年的第一天是:" + date); // Duration 計算 LocalDateTime from = LocalDateTime.now(); LocalDateTime to = LocalDateTime.now().plusMonths(1); Duration duration = Duration.between(from, to); // 區間統計換算 // 總天數 long days = duration.toDays(); System.out.println("相隔" + days + "天"); // 小時數 long hours = duration.toHours(); System.out.println("相隔" + hours + "小時"); // 分鐘數 long minutes = duration.toMinutes(); System.out.println("相隔" + minutes + "分鐘"); }
TemporalAdjusters
的更多方法方法名稱 | 描述 |
---|---|
dayOfWeekInMonth() |
返回同一個月中每週的第幾天 |
firstDayOfMonth() |
返回當月的第一天 |
firstDayOfNextMonth() |
返回下月的第一天 |
firstDayOfNextYear() |
返回下一年的第一天 |
firstDayOfYear() |
返回本年的第一天 |
firstInMonth() |
返回同一個月中第一個星期幾 |
lastDayOfMonth() |
返回當月的最後一天 |
lastDayOfNextMonth() |
返回下月的最後一天 |
lastDayOfNextYear() |
返回下一年的最後一天 |
lastDayOfYear() |
返回本年的最後一天 |
lastInMonth() |
返回同一個月中最後一個星期幾 |
next() / previous() |
返回後一個/前一個給定的星期幾 |
nextOrSame() / previousOrSame() |
返回後一個/前一個給定的星期幾,若是這個值知足條件,直接返回 |
DateTimeFormatter
默認提供了多種格式化方式,若是默認提供的不能知足要求,能夠經過DateTimeFormatter
的ofPattern
方法建立自定義格式化方式。
public static void format() { LocalDate today = LocalDate.now(); // 兩種默認格式化時間方式 String todayStr1 = today.format(DateTimeFormatter.BASIC_ISO_DATE); String todayStr2 = today.format(DateTimeFormatter.ISO_LOCAL_DATE); System.out.println("格式化時間:" + todayStr1); System.out.println("格式化時間:" + todayStr2); //自定義格式化 DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); String todayStr3 = today.format(dateTimeFormatter); System.out.println("自定義格式化時間:" + todayStr3); }
4.1 中以何種方式格式化,這裏需以一樣方式解析。
public static void parse() { LocalDate date1 = LocalDate.parse("20080808", DateTimeFormatter.BASIC_ISO_DATE); LocalDate date2 = LocalDate.parse("2008-08-08", DateTimeFormatter.ISO_LOCAL_DATE); System.out.println(date1); System.out.println(date2); }
相較於
Date
的優點
Instant
的精確度更高,能夠精確到納秒級;Duration
能夠便捷獲得時間段內的天數、小時數等;LocalDateTime
可以快速地獲取年、月、日、下一月等;TemporalAdjusters
類中包含許多經常使用的靜態方法,避免本身編寫工具類;Date
的格式化方式SimpleDateFormat
相比,DateTimeFormatter
是線程安全的。