
你在项目中写如下一行代码来格式化时间会有啥危险?
/*** 定义一个全局的SimpleDateFormat*/private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
1.在阿里巴巴Java开发手册中,有如下明确规定:

2.SimpleDateFormat的线程安全性:

3.SimpleDateFormat为神马会有线程安全性问题?

protected Calendar calendar;4.如何解决
4.1使用局部变量(略)
4.2加同步锁
synchronized (simpleDateFormat) {,,,,,,,,,,,,,,,,,,}可以只对simpleDateFormat.format这一行加锁,这样效率更高一些
4.3使用ThreadLocal
/*** 使用ThreadLocal定义一个全局的SimpleDateFormat*/private static ThreadLocalsimpleDateFormatThreadLocal = new ThreadLocal () { @Overrideprotected SimpleDateFormat initialValue() {return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");}};//用法String dateString = simpleDateFormatThreadLocal.get().format(calendar.getTime());
4.4使用DateTimeFormatter
5.工具类
package xxxxx(自己的项目路径);import cn.hutool.core.collection.CollectionUtil;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.Period;import java.time.format.DateTimeFormatter;import java.time.temporal.TemporalAdjusters;import java.util.ArrayList;import java.util.List;/*** @author zlf* @description:* @time: 2021/10/10 16:27*/4jpublic class DateUtils {private static final DateTimeFormatter df1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");private static final DateTimeFormatter df2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");private static final DateTimeFormatter df3 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");private static final DateTimeFormatter df4 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");/*** 传入一个开始日期和结束日期(开始日期小于结束日期),返回这之间的日期天数,可以结合xxl-job等定时任务跑批处理开始时间至结束时间段的每一天额数据* @param startTime* @param endTime* @return*/public ListcalculationDays(String startTime, String endTime) {ListallDays = new ArrayList<>(); DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");LocalDate startDt = LocalDate.parse(startTime, dateTimeFormatter1);int start_Y = startDt.getYear();int start_M = startDt.getMonth().getValue();int start_D = startDt.getDayOfMonth();log.info("Y=" + start_Y + ",M=" + start_M + ",D=" + start_D);LocalDate endDt = LocalDate.parse(endTime, dateTimeFormatter1);int start_Y1 = endDt.getYear();int start_M1 = endDt.getMonth().getValue();int start_D1 = endDt.getDayOfMonth();log.info("Y1=" + start_Y1 + ",M1=" + start_M1 + ",D1=" + start_D1);if (startDt.compareTo(endDt) > 1) {//开始时间大于结束时间返回空!return null;}String endTimeStr = dateTimeFormatter1.format(endDt);Period period = Period.between(LocalDate.parse(startTime), endDt);StringBuffer sb = new StringBuffer();sb.append(period.getYears()).append(",").append(period.getMonths()).append(",").append(period.getDays());log.info("=======时间分量:=======" + sb.toString());int py = start_Y1 - start_Y;int Y = 12;detailYear(allDays, start_Y, py, Y);log.info("=======allDays--size()=======" + allDays.size());if (CollectionUtil.isNotEmpty(allDays)) {for (int i = 0; i < allDays.size(); i++) {log.info(allDays.get(i) + "--------allDays------>第" + (i + 1) + "天");}ListokResult = getOkResult(allDays, startTime, endTimeStr); System.out.println("=======okResult--size()=======" + okResult.size());for (int i = 0; i < okResult.size(); i++) {log.info(okResult.get(i) + "--------okResult-------->第" + (i + 1));}return okResult;}return null;}/*** 获取正确的List** @param startTime* @param allDays* @return*/private static ListgetOkResult(List {allDays, String startTime, String endTime) Listresult = new ArrayList<>(); int indexStart = 0;int indexEnd = 0;for (int i = 0; i < allDays.size(); i++) {if (allDays.get(i).equals(startTime)) {indexStart = i;}}for (int i = 0; i < allDays.size(); i++) {if (allDays.get(i).equals(endTime)) {indexEnd = i;}}result = allDays.subList(indexStart, indexEnd + 1);return result;}/*** 处理整年** @param allDays* @param start_Y* @param py* @param y*/private void detailYear(ListallDays, int start_Y, int py, int y) {//处理年的天for (int i = start_Y; i < start_Y + py + 1; i++) {for (int j = 1; j <= y; j++) {String fst = "";if (j <= 9) {fst = i + "-0" + j + "-01";} else {fst = i + "-" + j + "-01";}int diff_day = getDiff_day(fst);for (int k = 1; k <= diff_day + 1; k++) {String d = "";if (j <= 9) {d = i + "-0" + j;if (k <= 9) {d += "-0" + k;} else if (k > 9) {d += "-" + k;}} else if (j > 9) {d = i + "-" + j;if (k <= 9) {d += "-0" + k;} else if (k > 9) {d += "-" + k;}}allDays.add(d);}}}}/*** 根据当月第一天计算本月的开始天和结束天** @param fst* @return*/private int getDiff_day(String fst) {LocalDate fstLd = LocalDate.parse(fst);//获取月的第一天LocalDate fstLd_fd = fstLd.with(TemporalAdjusters.firstDayOfMonth());//获取月的最后一天LocalDate fstLd_ld = fstLd.with(TemporalAdjusters.lastDayOfMonth());Period period2 = Period.between(fstLd_fd, fstLd_ld);int diff_day = period2.getDays();return diff_day;}/*** LocalDateTime转String,格式是:yyyy-MM-dd HH:mm:ss* @param localDateTime* @return*/public static String localDateTimeToString(LocalDateTime localDateTime) {String format = df1.format(localDateTime);return format;}/*** LocalDateTime转String,格式是:yyyy-MM-dd* @param localDateTime* @return*/public static String localDateTimeToStringToYMD(LocalDateTime localDateTime) {String format = df2.format(localDateTime);return format;}/*** String转LocalDateTime,格式是:yyyy-MM-dd HH:mm:ss* @param dateTimeStr* @return*/public static LocalDateTime stringToLocalDateTime(String dateTimeStr) {LocalDateTime localDateTime = LocalDateTime.parse(dateTimeStr, df1);return localDateTime;}/*** String转LocalDateTime,格式是:yyyy-MM-dd* @param dateTimeStr* @return*/public static LocalDateTime stringIncludeTStrToLocalDateTime(String dateTimeStr) {LocalDateTime localDateTime = LocalDateTime.parse(dateTimeStr, df3);return localDateTime;}/*** LocalDateTime转String,格式是:yyyy-MM-dd'T'HH:mm:ss.SSS* @param localDateTime* @return*/public static String localDateTimeToStringT(LocalDateTime localDateTime) {String format = df3.format(localDateTime);return format;}/*** LocalDateTime转String,格式是:yyyy-MM-dd'T'HH:mm:ss* @param localDateTime* @return*/public static String localDateTimeToStringT2(LocalDateTime localDateTime) {String format = df4.format(localDateTime).replace("T", " ");return format;}/*** data转String* @param date* @return*/public static String DateToString(Date date) {Instant instant = date.toInstant();ZoneId zoneId = ZoneId.systemDefault();ZonedDateTime zonedDateTime = instant.atZone(zoneId);LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();// 或者直接使用LocalDateTime.ofInstantLocalDateTime localDateTime1 = LocalDateTime.ofInstant(instant, zoneId);DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");return dateTimeFormatter1.format(localDateTime);}}