本文工作
本文記錄瞭如何使用JDK8基於DateTimeFormatter和LocalDateTime的工具類JDK8DateUtils取代舊版的基於SimpleDateFormat和Date的工具類DateUtils,在此過程中使用JUnit和Assert作爲工具進行平滑過渡升級,將代碼中調用DateUtils方法之處全部更換爲JDK8DateUtils中的同功能方法。
爲什麼要使用JDK8的日期特性
引用《碼出高效-阿里巴巴開發手冊V1.4.0》中的解釋:
來自廖雪峯的點評:
Java8新增了LocalDate和LocalTime接口,爲什麼要搞一套全新的處理日期和時間的API?因爲舊的java.util.Date實在是太難用了。
java.util.Date月份從0開始,一月是0,十二月是11,變態吧!java.time.LocalDate月份和星期都改成了enum,就不可能再用錯了。
java.util.Date和SimpleDateFormatter都不是線程安全的,而LocalDate和LocalTime和最基本的String一樣,是不變類型,不但線程安全,而且不能修改。
java.util.Date是一個“萬能接口”,它包含日期、時間,還有毫秒數,如果你只想用java.util.Date存儲日期,或者只存儲時間,那麼,只有你知道哪些部分的數據是有用的,哪些部分的數據是不能用的。在新的Java 8中,日期和時間被明確劃分爲LocalDate和LocalTime,LocalDate無法包含時間,LocalTime無法包含日期。當然,LocalDateTime才能同時包含日期和時間。
新接口更好用的原因是考慮到了日期時間的操作,經常發生往前推或往後推幾天的情況。用java.util.Date配合Calendar要寫好多代碼,而且一般的開發人員還不一定能寫對。
Old DateUtils
package com.jake.manager.util;
import com.jake.manager.constant.DateConstants;
import com.jake.manager.constant.TimeConstants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* only for testing whether JDK8DateUtils works
* @deprecated
*/
class DateUtils {
private DateUtils() {
}
private static final Logger logger = LoggerFactory.getLogger(DateUtils.class);
/**
* @return 獲取當前日期yyyy-MM-dd
*/
static String getCurrentDateStr() {
return new SimpleDateFormat(DateConstants.YEAR_MONTH_DAY).format(new Date());
}
/**
* @return 獲取當前時間的整點時間字符串yyyy-MM-dd HH:00
*/
static String getCurrentZeroMinuteDateTimeStr() {
String currentMinuteTime = new SimpleDateFormat(DateConstants.YEAR_MONTH_DAY_HOUR_MINUTE)
.format(new Date());
String[] splitTime = StringUtils.split(currentMinuteTime, ":");
return splitTime[0] + ":00";
}
/**
* @param time 傳入時間參數yyyy-MM-dd HH:mm
* @return 返回傳入時間的整點時間
*/
static String getZeroMinuteDateTimeStr(String time) {
return getHourByAddHour(time, 0);
}
/**
* @param time 傳入時間爲查詢起始時間,參數yyyy-MM-dd HH:mm
* @return yyyy-MM-dd HH:00 返回查詢起始時間對應的合理的整點時間:若起始時間爲整點,則返回該整點時間;
* 若不爲整點,則返回下一個整點時間。
*/
static String getStartZeroMinuteDateTimeStr(String time) {
return getHourByAddHour(time, 1);
}
private static String getHourByAddHour(String time, int add) {
if (!StringUtils.endsWith(time, "00")) {
String[] splitTime = StringUtils.split(time, " ");
String[] splitTime2 = StringUtils.split(splitTime[1], ":");
int addedHour = Integer.parseInt(splitTime2[0]) + add;
String joint = addedHour < 10?" 0": " ";
time = splitTime[0] + joint + addedHour + ":00";
}
return time;
}
/**
* @param startDateTime 開始時間(格式爲字符串yyyy-MM-dd)
* @param endDateTime 結束時間(格式爲字符串yyyy-MM-dd)
* @param calUnit 間隔單位,Calendar類裏的常量,年月週日時分秒
* @param interval 間隔大小,每隔多久獲取一次時間
* @return 返回時間集合(格式爲字符串yyyy-MM-dd)
*/
static Set<String> getBetweenDateStrsEveryDay(String startDateTime, String endDateTime, int calUnit, int interval) {
Set<String> dateTimes = new TreeSet<>(Comparator.naturalOrder());
String startMinuteTime = startDateTime + TimeConstants.HOUR_MINUTE_SUFFIX;
String endMinuteTime = endDateTime + TimeConstants.HOUR_MINUTE_SUFFIX;
Set<String> minuteTimes = getBetweenMinuteDateTimeStrsEveryHour(startMinuteTime, endMinuteTime, calUnit, interval);
for (String minuteTime : minuteTimes) {
String[] split = minuteTime.split(" ");
dateTimes.add(split[0]);
}
return dateTimes;
}
/**
* @param startTime 開始時間(格式爲字符串yyyy-MM-dd HH:mm)
* @param endTime 結束時間(格式爲字符串yyyy-MM-dd HH:mm)
* @param calUnit 間隔單位,Calendar類裏的常量,年月週日時分秒
* @param interval 間隔大小,每隔多久獲取一次時間
* @return 返回時間集合(格式爲字符串yyyy-MM-dd HH:mm)
*/
static Set<String> getBetweenMinuteDateTimeStrsEveryHour(String startTime, String endTime, int calUnit, int interval) {
SimpleDateFormat sdfMinute = new SimpleDateFormat(DateConstants.YEAR_MONTH_DAY_HOUR_MINUTE);
Set<String> times = new TreeSet<>(Comparator.naturalOrder());
try {
Date startDate = sdfMinute.parse(startTime);
Date endDate = sdfMinute.parse(endTime);
Calendar startCal = Calendar.getInstance();
startCal.setTime(startDate);
times.add(startTime);
while (startCal.getTime().before(endDate)) {
startCal.add(calUnit, interval);
times.add(sdfMinute.format(startCal.getTime()));
}
} catch (ParseException e) {
logger.error(e.getMessage());
}
return times;
}
/**
* @param dateTime yyyy-MM-dd
* @return 返回當前日期的下一天 yyyy-MM-dd
*/
static String getNextDayDateStr(String dateTime) {
String minuteTime = dateTime + TimeConstants.HOUR_MINUTE_SUFFIX;
String[] split = getOtherTimeByInterval(minuteTime, Calendar.DATE, 1).split(" ");
return split[0];
}
/**
* @param dateTime yyyy-MM-dd
* @return 返回當前日期的前一天 yyyy-MM-dd
*/
static String getLastDayDateStr(String dateTime) {
String minuteTime = dateTime + TimeConstants.HOUR_MINUTE_SUFFIX;
String[] split = getOtherTimeByInterval(minuteTime, Calendar.DATE, -1).split(" ");
return split[0];
}
/**
* @return 獲取當前時間對應的上一個小時的整點時間,
* 如傳參 "2019-03-26 19:58",返回"2019-03-26 18:00"
* 傳參 "2019-03-26 19:00",返回"2019-03-26 18:00"
*/
static String getLastZeroMinuteDateTimeStr(String time) {
String lastTime = getOtherTimeByInterval(time, Calendar.HOUR_OF_DAY, -1);
return getZeroMinuteDateTimeStr(lastTime);
}
/**
* @return 獲取當前時間對應的下一個小時的整點時間,
*/
static String getNextZeroMinuteDateTimeStr(String time) {
String nextTime = getOtherTimeByInterval(time, Calendar.HOUR_OF_DAY, 1);
return getZeroMinuteDateTimeStr(nextTime);
}
/**
* @param time 傳入時間
* @param calUnit 間隔單位,如:Calendar.MINUTE
* @return 獲取與傳入時間相隔N個時間單位的另一個時間
*/
private static String getOtherTimeByInterval(String time, int calUnit, int interval) {
SimpleDateFormat sdfMinute = new SimpleDateFormat(DateConstants.YEAR_MONTH_DAY_HOUR_MINUTE);
String otherTime = "";
Calendar calendar = Calendar.getInstance();
try {
Date date = sdfMinute.parse(time);
calendar.setTime(date);
calendar.add(calUnit, interval);
Date lastDate = calendar.getTime();
otherTime = sdfMinute.format(lastDate);
} catch (ParseException e) {
logger.error(e.getMessage());
}
return otherTime;
}
/**
* @param startDateTime 開始時間(格式爲字符串yyyy-MM-dd)
* @param endDateTime 結束時間(格式爲字符串yyyy-MM-dd)
* @return 獲取間隔天數
*/
static long countDaysBetweenDateStrs(String startDateTime, String endDateTime) {
String startMinuteTime = startDateTime + TimeConstants.HOUR_MINUTE_SUFFIX;
String endMinuteTime = endDateTime + TimeConstants.HOUR_MINUTE_SUFFIX;
return countDaysBetweenMinuteDateTimeStrs(startMinuteTime, endMinuteTime);
}
/**
* @param startTime 開始時間(格式爲字符串yyyy-MM-dd HH:mm)
* @param endTime 結束時間(格式爲字符串yyyy-MM-dd HH:mm)
* @return 獲取間隔天數
*/
static long countDaysBetweenMinuteDateTimeStrs(String startTime, String endTime) {
SimpleDateFormat sdfMinute = new SimpleDateFormat(DateConstants.YEAR_MONTH_DAY_HOUR_MINUTE);
long days = -1024;
if (StringUtils.compare(startTime, endTime) < 0) {
try {
Date startDate = sdfMinute.parse(startTime);
Date endDate = sdfMinute.parse(endTime);
days = (endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24);
} catch (ParseException e) {
logger.error(e.getMessage());
}
}
return days;
}
/**
* @param dateTime yyyy-MM-dd
* @param days 負數代表傳入日期幾天前的日期,正數代表傳入日期幾天後的日期。
* @return 得到與當前時間相距幾天的時間 yyyy-MM-dd
*/
static String getDateStrDaysApart(String dateTime, int days) {
String minuteTime = dateTime + TimeConstants.HOUR_MINUTE_SUFFIX;
String addedMinuteTime = getMinuteDateTimeStrDaysApart(minuteTime, days);
String[] splitMinuteTime = StringUtils.split(addedMinuteTime, " ");
return splitMinuteTime[0];
}
/**
* @param time 格式爲字符串yyyy-MM-dd HH:mm
* @param days 負數代表傳入日期幾天前的日期,正數代表傳入日期幾天後的日期。
* @return 得到與當前時間相距幾天的時間 yyyy-MM-dd HH:mm
*/
static String getMinuteDateTimeStrDaysApart(String time, int days) {
SimpleDateFormat sdfMinute = new SimpleDateFormat(DateConstants.YEAR_MONTH_DAY_HOUR_MINUTE);
Date addedDate = null;
try {
Calendar calendar = Calendar.getInstance();
Date date = sdfMinute.parse(time);
calendar.setTime(date);
calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + days);
addedDate = calendar.getTime();
} catch (ParseException e) {
logger.error(e.getMessage());
}
return sdfMinute.format(addedDate);
}
}
JDK8 DateUtils
此工具類中的方法實現了與舊版DateUtils同名方法完全相同的功能,即兩個類的同名方法入參相同的情況下,返回值也相同。
package com.jake.manager.util;
import org.apache.commons.lang3.StringUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class JDK8DateUtils {
private JDK8DateUtils() {
}
private static final String YEAR_MONTH_DAY_HOUR_MINUTE = "yyyy-MM-dd HH:mm";
private static final String YEAR_MONTH_DAY_HOUR_ZERO = "yyyy-MM-dd HH:00";
private static DateTimeFormatter dtfMinute = DateTimeFormatter.ofPattern(YEAR_MONTH_DAY_HOUR_MINUTE);
private static DateTimeFormatter dtfZeroMinute = DateTimeFormatter.ofPattern(YEAR_MONTH_DAY_HOUR_ZERO);
/**
* @return 獲取當前日期yyyy-MM-dd
*/
public static String getCurrentDateStr() {
return LocalDate.now().toString();
}
/**
* @return 獲取當前時間的整點時間字符串yyyy-MM-dd HH:00
*/
public static String getCurrentZeroMinuteDateTimeStr() {
return dtfZeroMinute.format(LocalDateTime.now());
}
/**
* @param minuteDateTimeStr 傳入時間參數yyyy-MM-dd HH:mm
* @return 返回傳入時間的整點時間
*/
public static String getZeroMinuteDateTimeStr(String minuteDateTimeStr) {
return dtfZeroMinute.format(LocalDateTime.parse(minuteDateTimeStr, dtfMinute));
}
/**
* @param minuteDateTimeStr 傳入時間爲查詢起始時間,參數yyyy-MM-dd HH:mm
* @return yyyy-MM-dd HH:00 返回查詢起始時間對應的合理的整點時間:若起始時間爲整點,則返回該整點時間;
* 若不爲整點,則返回下一個整點時間。
*/
public static String getStartZeroMinuteDateTimeStr(String minuteDateTimeStr) {
if (!StringUtils.endsWith(minuteDateTimeStr, ":00")) {
LocalDateTime currentDateTime = LocalDateTime.parse(minuteDateTimeStr, dtfMinute);
LocalDateTime nextDateTime = currentDateTime.plusHours(1);
return dtfZeroMinute.format(nextDateTime);
}
return minuteDateTimeStr;
}
/**
* @param startDateStr 開始時間(格式爲字符串yyyy-MM-dd)
* @param endDateStr 結束時間(格式爲字符串yyyy-MM-dd)
* @return 返回時間集合(格式爲字符串yyyy-MM-dd)
*/
public static Set<String> getBetweenDateStrsEveryDay(String startDateStr, String endDateStr) {
Set<String> dateStrs = new TreeSet<>(Comparator.naturalOrder());
LocalDate startDate = LocalDate.parse(startDateStr);
LocalDate endDate = LocalDate.parse(endDateStr);
dateStrs.add(startDateStr);
while (startDate.isBefore(endDate)) {
startDate = startDate.plusDays(1);
dateStrs.add(startDate.toString());
}
return dateStrs;
}
/**
* @param startMinDateTimeStr 開始時間(格式爲字符串yyyy-MM-dd HH:mm)
* @param endMinDateTimeStr 結束時間(格式爲字符串yyyy-MM-dd HH:mm)
* @return 返回時間集合(格式爲字符串yyyy-MM-dd HH:mm)
*/
public static Set<String> getBetweenMinuteDateTimeStrsEveryHour(String startMinDateTimeStr, String endMinDateTimeStr) {
Set<String> timeStrs = new TreeSet<>(Comparator.naturalOrder());
LocalDateTime startDateTime = LocalDateTime.parse(startMinDateTimeStr, dtfMinute);
LocalDateTime endDateTime = LocalDateTime.parse(endMinDateTimeStr, dtfMinute);
timeStrs.add(startMinDateTimeStr);
while (startDateTime.isBefore(endDateTime)) {
startDateTime = startDateTime.plusHours(1);
timeStrs.add(StringUtils.replace(startDateTime.toString(), "T", " "));
}
return timeStrs;
}
/**
* @param dateStr yyyy-MM-dd
* @return 返回當前日期的下一天 yyyy-MM-dd
*/
public static String getNextDayDateStr(String dateStr) {
return LocalDate.parse(dateStr).plusDays(1).toString();
}
/**
* @param dateStr yyyy-MM-dd
* @return 返回當前日期的前一天 yyyy-MM-dd
*/
public static String getLastDayDateStr(String dateStr) {
return LocalDate.parse(dateStr).minusDays(1).toString();
}
/**
* @param minuteDateTimeStr yyyy-MM-dd HH:mm
* @return 獲取當前時間對應的上一個小時的整點時間,
* 如傳參 "2019-03-26 19:58",返回"2019-03-26 18:00"
* 傳參 "2019-03-26 19:00",返回"2019-03-26 18:00"
*/
public static String getLastZeroMinuteDateTimeStr(String minuteDateTimeStr) {
LocalDateTime lastMinuteDateTime = LocalDateTime.parse(minuteDateTimeStr, dtfMinute).minusHours(1);
return dtfZeroMinute.format(lastMinuteDateTime);
}
/**
* @param minuteDateTimeStr yyyy-MM-dd HH:mm
* @return 獲取當前時間對應的下一個小時的整點時間,
*/
public static String getNextZeroMinuteDateTimeStr(String minuteDateTimeStr) {
LocalDateTime nextMinuteDateTime = LocalDateTime.parse(minuteDateTimeStr, dtfMinute).plusHours(1);
return dtfZeroMinute.format(nextMinuteDateTime);
}
/**
* @param startDateStr 開始時間(格式爲字符串yyyy-MM-dd)
* @param endDateStr 結束時間(格式爲字符串yyyy-MM-dd)
* @return 獲取間隔天數
*/
public static long countDaysBetweenDateStrs(String startDateStr, String endDateStr) {
return ChronoUnit.DAYS.between(LocalDate.parse(startDateStr), LocalDate.parse(endDateStr));
}
/**
* @param startMinDateTimeStr 開始時間(格式爲字符串yyyy-MM-dd HH:mm)
* @param endMinDateTimeStr 結束時間(格式爲字符串yyyy-MM-dd HH:mm)
* @return 獲取間隔天數
*/
public static long countDaysBetweenMinuteDateTimeStrs(String startMinDateTimeStr, String endMinDateTimeStr) {
return ChronoUnit.DAYS.between(LocalDateTime.parse(startMinDateTimeStr, dtfMinute),
LocalDateTime.parse(endMinDateTimeStr, dtfMinute));
}
/**
* @param dateStr yyyy-MM-dd
* @param days 負數代表傳入日期幾天前的日期,正數代表傳入日期幾天後的日期。
* @return 得到與當前時間相距幾天的時間 yyyy-MM-dd
*/
public static String getDateStrDaysApart(String dateStr, int days) {
return LocalDate.parse(dateStr).plusDays(days).toString();
}
/**
* @param minuteDateTimeStr 格式爲字符串yyyy-MM-dd HH:mm
* @param days 負數代表傳入日期幾天前的日期,正數代表傳入日期幾天後的日期。
* @return 得到與當前時間相距幾天的時間 yyyy-MM-dd HH:mm
*/
public static String getMinuteDateTimeStrDaysApart(String minuteDateTimeStr, int days) {
return StringUtils.replace(LocalDateTime.parse(minuteDateTimeStr, dtfMinute).plusDays(days).toString(), "T", " ");
}
}
JUnit Assert for code updagrade
使用JUnit Assert進行JDK8DateUtils和DateUtils同名方法的返回值校驗。注意僅調用靜態方法的單元測試類不需要加入以下註解:
@RunWith(SpringRunner.class)
@SpringBootTest
JDK8DateUtilsTests
package com.jake.manager.util;
import org.junit.Test;
import java.util.Calendar;
import static org.junit.Assert.*;
public class JDK8DateUtilsTests {
@Test
public void getCurrentDateStr() {
assertEquals(DateUtils.getCurrentDateStr(), JDK8DateUtils.getCurrentDateStr());
}
@Test
public void getCurrentZeroMinuteDateTimeStr() {
assertEquals(DateUtils.getCurrentZeroMinuteDateTimeStr(), JDK8DateUtils.getCurrentZeroMinuteDateTimeStr());
}
@Test
public void getZeroMinuteDateTimeStr() {
String time = "2019-06-25 15:28";
assertEquals(DateUtils.getZeroMinuteDateTimeStr(time), JDK8DateUtils.getZeroMinuteDateTimeStr(time));
}
@Test
public void getStartZeroMinuteDateTimeStr() {
String time = "2019-06-25 16:32";
assertEquals(DateUtils.getStartZeroMinuteDateTimeStr(time), JDK8DateUtils.getStartZeroMinuteDateTimeStr(time));
}
@Test
public void getBetweenDateStrsEveryDay() {
String startDate = "2019-01-01";
String endDate = "2019-03-05";
String[] jdk7DateArray = DateUtils.getBetweenDateStrsEveryDay(startDate, endDate,
Calendar.DATE, 1).toArray(new String[0]);
String[] jdk8DateArray = JDK8DateUtils.getBetweenDateStrsEveryDay(startDate,
endDate).toArray(new String[0]);
assertArrayEquals(jdk7DateArray, jdk8DateArray);
}
@Test
public void getBetweenMinuteDateTimeStrsEveryHour() {
String startTime = "2019-01-01 12:00";
String endTime = "2019-02-01 16:00";
String[] jdk7TimeArray = DateUtils.getBetweenMinuteDateTimeStrsEveryHour(startTime, endTime,
Calendar.HOUR_OF_DAY, 1).toArray(new String[0]);
String[] jdk8TimeArray = JDK8DateUtils.getBetweenMinuteDateTimeStrsEveryHour(startTime,
endTime).toArray(new String[0]);
assertArrayEquals(jdk7TimeArray, jdk8TimeArray);
}
@Test
public void getNextDayDateStr() {
String date = "2019-06-26";
assertEquals(DateUtils.getNextDayDateStr(date), JDK8DateUtils.getNextDayDateStr(date));
}
@Test
public void getLastDayDateStr() {
String date = "2019-06-26";
assertEquals(DateUtils.getLastDayDateStr(date), JDK8DateUtils.getLastDayDateStr(date));
}
@Test
public void getLastZeroMinuteDateTimeStr() {
String minuteTime = "2019-06-26 10:49";
String zeroMinuteTime = "2019-06-26 10:00";
assertEquals(DateUtils.getLastZeroMinuteDateTimeStr(minuteTime),
JDK8DateUtils.getLastZeroMinuteDateTimeStr(minuteTime));
assertEquals(DateUtils.getLastZeroMinuteDateTimeStr(zeroMinuteTime),
JDK8DateUtils.getLastZeroMinuteDateTimeStr(zeroMinuteTime));
}
@Test
public void getNextZeroMinuteDateTimeStr() {
String minuteTime = "2019-06-26 10:49";
String zeroMinuteTime = "2019-06-26 10:00";
assertEquals(DateUtils.getNextZeroMinuteDateTimeStr(minuteTime),
JDK8DateUtils.getNextZeroMinuteDateTimeStr(minuteTime));
assertEquals(DateUtils.getNextZeroMinuteDateTimeStr(zeroMinuteTime),
JDK8DateUtils.getNextZeroMinuteDateTimeStr(zeroMinuteTime));
}
@Test
public void countDaysBetweenDateStrs() {
String startDate = "2019-02-01";
String endDate = "2019-06-27";
assertEquals(DateUtils.countDaysBetweenDateStrs(startDate, endDate),
JDK8DateUtils.countDaysBetweenDateStrs(startDate, endDate));
}
@Test
public void countDaysBetweenMinuteDateTimeStrs() {
String startTime = "2019-02-01 12:30";
String endTimeBefore = "2019-06-27 09:20";
String endTimeEqual = "2019-06-27 12:30";
String endTimeAfter = "2019-06-27 15:40";
assertEquals(DateUtils.countDaysBetweenMinuteDateTimeStrs(startTime, endTimeBefore),
JDK8DateUtils.countDaysBetweenMinuteDateTimeStrs(startTime, endTimeBefore));
assertEquals(DateUtils.countDaysBetweenMinuteDateTimeStrs(startTime, endTimeEqual),
JDK8DateUtils.countDaysBetweenMinuteDateTimeStrs(startTime, endTimeEqual));
assertEquals(DateUtils.countDaysBetweenMinuteDateTimeStrs(startTime, endTimeAfter),
JDK8DateUtils.countDaysBetweenMinuteDateTimeStrs(startTime, endTimeAfter));
}
@Test
public void getDateStrDaysApart() {
String date = "2019-06-27";
assertEquals(DateUtils.getDateStrDaysApart(date, 10),
JDK8DateUtils.getDateStrDaysApart(date, 10));
assertEquals(DateUtils.getDateStrDaysApart(date, -10),
JDK8DateUtils.getDateStrDaysApart(date, -10));
}
@Test
public void getMinuteDateTimeStrDaysApart() {
String minutetime = "2019-06-27 09:25";
assertEquals(DateUtils.getMinuteDateTimeStrDaysApart(minutetime, 10),
JDK8DateUtils.getMinuteDateTimeStrDaysApart(minutetime, 10));
assertEquals(DateUtils.getMinuteDateTimeStrDaysApart(minutetime, -10),
JDK8DateUtils.getMinuteDateTimeStrDaysApart(minutetime, -10));
}
}
單元測試全部通過後,在IntelliJ IDEA中使用全局替換快捷鍵Ctrl + Shift + R做DateUtils替換爲JDK8DateUtils的類名替換,注意僅替換main source中的工具類方法調用處,然後修正一下Build報錯處。由此,便完成了代碼升級,項目中所有的日期相關邏輯都變爲使用JDK8處理。