记录搬砖路上的小bug之线程异常SimpleDateFormat
昨天分享的DateUtils获取当月开始结束时间,当周开始结束时间在今天的测试中发现了点线程安全问题。SimpleDateFormat作为线程不安全的类,把它用static修饰共享在类中,在短时间快速调用接口的情况下会报线程安全问题。 解决方案如下:
1.使用java8线程安全类DateTimeFormatter代替SimpleDateFormat
2.把公共得SimpleDateFormat定义到每个方法中
// 获取当月开始时间 结束时间工具类
public class DateUtils {
// 获得本周一与当前日期相差的天数
public static int getMondayPlus() {
Calendar cd = Calendar.getInstance();
int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == 1) {
return -6;
} else {
return 2 - dayOfWeek;
}
}
// 获得当前周- 周一的日期
public static String getCurrentMonday() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int mondayPlus = getMondayPlus();
GregorianCalendar currentDate = new GregorianCalendar();
currentDate.add(GregorianCalendar.DATE, mondayPlus);
Date monday = currentDate.getTime();
//DateFormat df = DateFormat.getDateInstance();
String preMonday = dateFormat.format(monday).split(" ")[0]+" 00:00:00";
return preMonday;
}
// 获得当前周- 周日 的日期
public static String getPreviousSunday() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int mondayPlus = getMondayPlus();
GregorianCalendar currentDate = new GregorianCalendar();
currentDate.add(GregorianCalendar.DATE, mondayPlus +6);
Date monday = currentDate.getTime();
//DateFormat df = DateFormat.getDateInstance();
String preMonday = dateFormat.format(monday).split(" ")[0]+" 23:59:59";
return preMonday;
}
// 获得当前月--开始日期
public static String getMinMonthDate() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar calendar = Calendar.getInstance();
try {
calendar.setTime(new Date());
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
return dateFormat.format(calendar.getTime()).split(" ")[0]+" 00:00:00";
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 获得当前月--结束日期
public static String getMaxMonthDate(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar calendar = Calendar.getInstance();
try {
calendar.setTime(new Date());
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
return dateFormat.format(calendar.getTime()).split(" ")[0]+" 23:59:59";
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
工具类如上↑:
在之后的功能开发过程中 通过日期范围查询数据库的数据,出现了在0点00分的数据获取不到 因为传参为date类型 解决方案为 把date类型的时间转换为 时间戳 在减去1 之后在转换为date类型 问题解决。 目前不是很清楚是什么原因产生的这种情况。 有大佬了解希望评论解决一下 = =
附上代码片段
// 解决方案
String startTime =null;
String endTime = null;
if(dutyWorkParam.getDateType().equals("day")){
startTime = DateFormatUtil.getTodayStartTime();
endTime = DateFormatUtil.getTodayEndTime();
}else if(dutyWorkParam.getDateType().equals("week")){
startTime = DateUtils.getCurrentMonday();
endTime = DateUtils.getPreviousSunday();
}else if(dutyWorkParam.getDateType().equals("month")){
startTime = DateUtils.getMinMonthDate();
endTime = DateUtils.getMaxMonthDate();
}
Date startDate = dateFormat.parse(startTime);
long timeString = startDate.getTime() - 1;
Date date = new Date(timeString);
Date endDate = dateFormat.parse(endTime);