Java 8通過發布新的Date-Time API (JSR 310)來進一步加強對日期與時間的處理。那么,之前已經有了標準的 java.util.Date以及后來的java.util.Calendar,為什么還要搞一個Date-Time的API呢?
我們先看看原先的Date是如何獲取以及格式化的
原始Date
Date date = new Date();
System.out.println(date);
這樣輸出的結果:
file
我們來解析:
Wed Oct 23 18:31:33 CST 2019
星期三 十月 23日 當前時間(標準時間) 年份
可讀性太差了,反正很讓我反感。那么有人就說了,不是有個SimpleDateFormat可以進行格式化嗎?好,我們再按照SimpleDateFormat進行格式化
Date date = new Date();
System.out.println(date);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
System.out.println(sdf.format(date));
輸出結果
file
這樣的結果確實是很人性化,一看就明白~但是,在alibaba開發規范手冊中卻不建議我們直接使用SimpleDateFormat呢?
我們可以從它的源碼看問題,
private StringBuffer format(Date date, StringBuffer toAppendTo,
FieldDelegate delegate) {
// Convert input date to time field list
calendar.setTime(date);
boolean useDateFormatSymbols = useDateFormatSymbols();
for (int i = 0; i < compiledPattern.length; ) {
int tag = compiledPattern[i] >>> 8;
int count = compiledPattern[i++] & 0xff;
if (count == 255) {
count = compiledPattern[i++] << 16;
count |= compiledPattern[i++];
}
switch (tag) {
case TAG_QUOTE_ASCII_CHAR:
toAppendTo.append((char)count);
break;
case TAG_QUOTE_CHARS:
toAppendTo.append(compiledPattern, i, count);
i += count;
break;
default:
subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
break;
}
}
return toAppendTo;
}
其中calendar這個是共享變量,多線程場景下時使用相同的SimpleDateFormat對象造成沖突,所以線程不安全。所以建議我們使用Java8的Date-Time的API。
java8的Date-Time API
java8新的Date-Time 的API的對日期時間的創建、格式化、解析、計算、修改使用方式很方便。
LocalDate對日期的api
LocalDate localDate = LocalDate.now();
System.out.println("當前日期:"+localDate);
System.out.println("當前年份:"+localDate.getYear());
System.out.println("當前月份:"+localDate.getMonth().getValue());
System.out.println("當前在當前月份中的天數:"+localDate.getDayOfMonth());
System.out.println("當前在當前日期的天數:"+localDate.getDayOfYear());
System.out.println("星期幾:"+localDate.getDayOfWeek().getValue());
System.out.println("往后推兩天的日期是:"+localDate.plusDays(2));
System.out.println("往前推兩天的日期是:"+localDate.minusDays(2));
System.out.println("往后推兩個月的日期是:"+localDate.plusMonths(2));
System.out.println("往前推兩個月的日期是:"+localDate.minusMonths(2));
System.out.println("往后推兩年的日期是:"+localDate.plusYears(2));
System.out.println("往前推兩年的日期是:"+localDate.minusYears(2));
System.out.println("修改日期至2025年:"+localDate.withYear(2025));
System.out.println("修改日期至2025年1月:"+localDate.withYear(2025).withMonth(1));
System.out.println("修改日期至2025年1月5日:"+localDate.withYear(2025).withMonth(1).withDayOfMonth(5));
以上輸出結果:
file
LocalTime對時間的api
LocalTime localTime = LocalTime.now();
System.out.println("當前時間:"+localTime);
System.out.println("當前幾點:"+localTime.getHour());
System.out.println("當前幾分:"+localTime.getMinute());
System.out.println("當前幾秒:"+localTime.getSecond());
System.out.println("當前幾毫秒:"+localTime.getNano());
System.out.println("當前往后推2小時的時間:"+localTime.plusHours(2));
System.out.println("當前往前推2小時的時間:"+localTime.minusHours(2));
System.out.println("當前往后推2分鐘的時間:"+localTime.plusMinutes(2));
System.out.println("當前往前推2分鐘的時間:"+localTime.minusMinutes(2));
System.out.println("當前往后推2秒的時間:"+localTime.plusSeconds(2));
System.out.println("當前往前推2秒的時間:"+localTime.minusSeconds(2));
System.out.println("修改時間至20點:"+localTime.withHour(20));
System.out.println("修改時間至20點30分:"+localTime.withHour(20).withMinute(30));
System.out.println("修改時間至20點30分49秒:"+localTime.withHour(20).withMinute(30).withSecond(49));
以上輸出結果:
file
LocalDateTime對日期時間的api以及格式化
LocalDateTime就是LocalDate與LocalTime的結合,LocalDate與LocalTime擁有的功能,LocalDateTime也同樣擁有。因此我們重點來看看它的格式化
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("當前日期時間:"+localDateTime);
System.out.println("當前日期時間格式話之后:" + localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS")));
以上輸出結果:
file
總結
- LocalDate、LocalTime、LocalDateTim不可變對象(源碼中都類的定義使用了final修飾,成員變量也是),修改這些對象對象會返回一個副本。
- Java8對日期時間的操作明顯優于標準的 java.util.Date以及后來的java.util.Calendar。
本人水平有限,難免有錯誤或遺漏之處,望大家指正和諒解,提出寶貴意見,愿與之交流。