package com.skua.tool.util; import com.skua.constant.BaseConstant; import com.skua.modules.common.vo.DateVO; import java.math.BigDecimal; import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.time.DayOfWeek; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.YearMonth; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.*; /** * <pre> * 日期工具类 * </pre> * * @author sonin * @version 1.0 2022/4/20 17:22 */ public class DateUtils { public static String dateformat(String date,String format){ SimpleDateFormat sdf = new SimpleDateFormat(format); return sdf.format(str2Date(date,format)); } public static ThreadLocal<SimpleDateFormat> date_sdf = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; public static ThreadLocal<SimpleDateFormat> yyyyMMdd = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyyMMdd"); } }; public static ThreadLocal<SimpleDateFormat> date_sdf_wz = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy年MM月dd日"); } }; public static ThreadLocal<SimpleDateFormat> time_sdf = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm"); } }; public static ThreadLocal<SimpleDateFormat> yyyymmddhhmmss = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyyMMddHHmmss"); } }; public static ThreadLocal<SimpleDateFormat> short_time_sdf = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("HH:mm"); } }; public static ThreadLocal<SimpleDateFormat> datetimeFormat = new ThreadLocal<SimpleDateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } }; public static void main(String[] args) { // System.out.println(getHbMonth(formatDate("2024-01-01","yyyy-MM"))); // 获取当前日期的Calendar实例 Calendar calendar = Calendar.getInstance(); // 将当前日期减去一个月 calendar.add(Calendar.MONTH, -1); // 创建日期格式化对象 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM"); // 格式化上个月的日期 String lastMonth = dateFormat.format(calendar.getTime()); calendar.add(Calendar.MONTH, -1); String lastMonth2 = dateFormat.format(calendar.getTime()); calendar.add(Calendar.MONTH, -11); String lastMonth3 = dateFormat.format(calendar.getTime()); System.out.println("上月"+lastMonth); System.out.println("上上月"+lastMonth2); System.out.println("同比"+lastMonth3); // System.out.println("天数差异: " + daysBetween); } /*** * 判断一个时间字符串是否表示当前月,并且如果它是当前月的话,再与当前时间进行比较 * @param endTime * @return */ public static String checkDateByCurrentDate(String endTime){ LocalDate currentDate = LocalDate.now(); // 定义日期格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 将字符串转换为LocalDate对象 LocalDate endDate = LocalDate.parse(endTime, formatter); System.out.println(endDate.getYear()); // 比较年份和月份 if (endDate.getYear() == currentDate.getYear() && endDate.getMonth() == currentDate.getMonth()) { // 如果是当前月,比较时间 if (currentDate.isBefore(endDate)) { // 当前时间小于给定时间,返回当前时间 // System.out.println("当前时间小于给定时间,当前时间: " + currentDate); return currentDate.toString(); } } return endTime; } /*** * 字符串日期格式化 * @param date * @param format * @return */ public static String formatDate(String date , String format){ if(format == null ){ format = "yyyy-MM-dd"; } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat formatSDF = new SimpleDateFormat(format); // 转化成日期类型 try { Date startDate = sdf.parse(date); date = formatSDF.format(startDate); } catch (ParseException e) { e.printStackTrace(); } return date; } public static Date str2Date(String str, String pattern) { Date d = null; SimpleDateFormat sdf = new SimpleDateFormat(pattern); try { d = sdf.parse(str); } catch (Exception e) { e.printStackTrace(); } return d; } /** * 两个时间相差的天数 * @param day1 * @param day2 * @return */ public static long differenceDay(String day1 ,String day2){ String format = "yyyy-MM-dd"; Date startDay = str2Date(day1,format); Date endDay = str2Date(day2,format); long msNum = endDay.getTime() - startDay.getTime(); long dayNUm = msNum /(24*60*60*1000); return dayNUm; } /** * 根据月份获取天数 * @param month * @return */ public static int getDayCountByMonth(String month){ YearMonth yearMonth = YearMonth.parse(month); return yearMonth.lengthOfMonth(); } /** * 根据(开始时间, 结束时间)获取每一个时间间隔的数据, 主要用于eCharts图标xData * * @param startTime * @param endTime * @param format * @return */ public static List<String> interval(String startTime, String endTime, String format, int field, int amount) { List<String> intervalList = new ArrayList<>(); try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); Date startDate = simpleDateFormat.parse(startTime); Date endDate = simpleDateFormat.parse(endTime); List<Date> dateList = new ArrayList<>(); dateList.add(startDate); Calendar calendarOfStart = Calendar.getInstance(); // 使用给定的 Date 设置此 Calendar 的时间 calendarOfStart.setTime(startDate); Calendar calendarOfEnd = Calendar.getInstance(); // 使用给定的 Date 设置此 Calendar 的时间 calendarOfEnd.setTime(endDate); // 测试此日期是否在指定日期之后 while (endDate.compareTo(calendarOfStart.getTime()) >= 0) { // 根据日历的规则,为给定的日历字段添加或减去指定的时间量 calendarOfStart.add(field, amount); if (endDate.compareTo(calendarOfStart.getTime()) >= 0 && !dateList.contains(calendarOfStart.getTime())) { dateList.add(calendarOfStart.getTime()); } } for (Date item : dateList) { intervalList.add(simpleDateFormat.format(item)); } } catch (Exception e) { e.printStackTrace(); } return intervalList; } public static List<String> intervalByHour(String startTime, String endTime, String format) { return interval(startTime, endTime, format, Calendar.HOUR_OF_DAY, 1); } public static List<String> intervalByDay(String startTime, String endTime, String format) { return interval(startTime, endTime, format, Calendar.DAY_OF_MONTH, 1); } public static List<String> intervalByMonth(String startTime, String endTime, String format) { return interval(startTime, endTime, format, Calendar.MONTH, 1); } public static List<String> intervalByYear(String startTime, String endTime, String format) { return interval(startTime, endTime, format, Calendar.YEAR, 1); } /** * 根据某个时间获取前多少天,或者后多少天 * * @param dateTime yyyy-MM-dd * @param limit 天数 * @return */ public static List<String> increaseDay(String dateTime, int limit) { return stepDay(dateTime, limit, true); } /** * 根据某个时间获取前多少天,或者后多少天 * * @param dateTime yyyy-MM-dd * @param limit 天数 * @return */ public static List<String> decreaseDay(String dateTime, int limit) { return stepDay(dateTime, limit, false); } private static List<String> stepDay(String dateTime, int limit, boolean flag) { LinkedList<String> dateList = new LinkedList<>(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Calendar calendar = Calendar.getInstance(); int factor = 1; if (!flag) { factor = -1; } for (int i = 0; i < limit; i++) { Date date = simpleDateFormat.parse(dateTime, new ParsePosition(0)); calendar.setTime(date); calendar.add(Calendar.DATE, factor * i); if (flag) { dateList.addLast(simpleDateFormat.format(calendar.getTime())); } else { dateList.addFirst(simpleDateFormat.format(calendar.getTime())); } } return dateList; } /** * <pre> * 根据某个日期获取指定时间 * </pre> * * @param currentDate * @param field: Calendar.DATE、Calendar.MONTH ... * @param step: step>0获取往后某一天,step<0获取之前某一天 * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static Date someDate(Date currentDate, Integer field, Integer step) { Calendar calendar = Calendar.getInstance(); calendar.setTime(currentDate); calendar.add(field, step); return calendar.getTime(); } /** * <pre> * 昨天此刻 * </pre> * * @param currentDate * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static Date prevDay(Date currentDate) { return someDate(currentDate, Calendar.DATE, -1); } /** * <pre> * 上个月此刻 * </pre> * * @param currentDate * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static Date prevMonth(Date currentDate) { return someDate(currentDate, Calendar.MONTH, -1); } /** * <pre> * 去年此刻 * </pre> * * @param currentDate * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static Date prevYear(Date currentDate) { return someDate(currentDate, Calendar.YEAR, -1); } /** * <pre> * 明天此刻 * </pre> * * @param currentDate * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static Date nextDay(Date currentDate) { return someDate(currentDate, Calendar.DATE, 1); } /** * <pre> * 下个月此刻 * </pre> * * @param currentDate * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static Date nextMonth(Date currentDate) { return someDate(currentDate, Calendar.MONTH, 1); } /** * <pre> * 明年此刻 * </pre> * * @param currentDate * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static Date nextYear(Date currentDate) { return someDate(currentDate, Calendar.YEAR, 1); } /** * <pre> * 获取某一周: 0:这周; -1:上一周; 1:下一周; * </pre> * * @param * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static List<String> someWeek(int n) { String format = "yyyy-MM-dd"; LocalDateTime now = LocalDateTime.now(); // 获取本周 DayOfWeek dayOfWeek = now.getDayOfWeek(); // 本周周一 String startTime = now.minusDays(dayOfWeek.getValue() - 1).format(DateTimeFormatter.ofPattern(format)); // 本周周日 String endTime = now.plusDays(7 - dayOfWeek.getValue()).format(DateTimeFormatter.ofPattern(format)); if (n != 0) { startTime = date2Str(someDate(strToDate(startTime, format), Calendar.DATE, n * 7), format); endTime = date2Str(someDate(strToDate(endTime, format), Calendar.DATE, n * 7), format); } return intervalByDay(startTime, endTime, format); } /** * <pre> * 获取某一个月: 0:这个月; -1:上一月; 1:下一月; * </pre> * * @param * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static List<String> someMonth(int n) { Date date = someDate(new Date(), Calendar.MONTH, n); Calendar calendar = Calendar.getInstance(Locale.CHINA); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); //年份 int month = calendar.get(Calendar.MONTH) + 1; //月份 int day = calendar.getActualMaximum(Calendar.DATE); // 天数 String startTime = year + "-" + (month < 10 ? ("0" + month) : month) + "-01"; String endTime = year + "-" + (month < 10 ? ("0" + month) : month) + "-" + day; return intervalByDay(startTime, endTime, "yyyy-MM-dd"); } /** * <pre> * 获取指定某一个月: 0:这个月; -1:上一月; 1:下一月; * </pre> * * @param currentDate * @param n * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static List<String> someMonth(Date currentDate, int n) { Date date = someDate(currentDate, Calendar.MONTH, n); Calendar calendar = Calendar.getInstance(Locale.CHINA); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); //年份 int month = calendar.get(Calendar.MONTH) + 1; //月份 int day = calendar.getActualMaximum(Calendar.DATE); // 天数 String startTime = year + "-" + (month < 10 ? ("0" + month) : month) + "-01"; String endTime = year + "-" + (month < 10 ? ("0" + month) : month) + "-" + day; return intervalByDay(startTime, endTime, "yyyy-MM-dd"); } /** * String => java.util.Date * * @param str 表示日期的字符串 * @param dateFormat 传入字符串的日期表示格式(如:"yyyy-MM-dd HH:mm:ss") * @return java.util.Date类型日期对象(如果转换失败则返回null) */ public static Date strToDate(String str, String dateFormat) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat); Date date = null; try { date = simpleDateFormat.parse(str); } catch (Exception e) { e.printStackTrace(); } return date; } /** * <pre> * java.util.Date => String * </pre> * * @param date * @param format * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static String date2Str(Date date, String format) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); return simpleDateFormat.format(date); } public static String date2Str(Date date, SimpleDateFormat date_sdf) { return null == date ? null : date_sdf.format(date); } /** * <pre> * 日期字符串转秒 * e.g: 2023-06-20 12:00:00 => 1687233600 * </pre> * * @param dateStr * @param format * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static Long dateStr2Sec(String dateStr, String format) { try { return new SimpleDateFormat(format).parse(dateStr).getTime() / 1000; } catch (Exception e) { e.printStackTrace(); } return null; } /** * <pre> * 秒转日期字符串 * e.g: 1687233600 => 2023-06-20 12:00:00 * </pre> * * @param sec * @param format * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static String sec2DateStr(long sec, String format) { return new SimpleDateFormat(format).format(new Date(sec * 1000)); } /** * <pre> * 获取最近月份集合 * </pre> * * @param * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static List<String> recentMonthList(int n) { List<String> yearMonthList = new ArrayList<>(); Calendar calendar = Calendar.getInstance(); // 1号就从上个月开始算 int num = 1; // 判断今天是否是1号 calendar.setTime(new Date()); calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1); if (calendar.get(Calendar.DAY_OF_MONTH) == 2) { num = 0; } calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + num); for (int i = n - 1; i >= 0; i--) { // 1个月前 calendar.add(Calendar.MONTH, -1); int month = calendar.get(Calendar.MONTH) + 1; String yearMonth = calendar.get(Calendar.YEAR) + "-" + (month < 10 ? ("0" + month) : ("" + month)); yearMonthList.add(yearMonth); } return yearMonthList; } /** * <pre> * 获取同比时间 * startTime与endTime不能超过一年 * </pre> * * @param startTime * @param endTime * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static String[] tbTime(String startTime, String endTime) { String yyyyOfStart = startTime.split("-")[0]; String yyyyOfEnd = endTime.split("-")[0]; String yyyyOfPrevStart = "" + (Integer.parseInt(yyyyOfStart) - 1); String yyyyOfPrevEnd = "" + (Integer.parseInt(yyyyOfEnd) - 1); return new String[]{startTime.replaceFirst(yyyyOfStart, yyyyOfPrevStart), endTime.replaceFirst(yyyyOfEnd, yyyyOfPrevEnd)}; } /** * <pre> * 某个月的天数 * </pre> * * @param year * @param month * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static int lengthOfSomeMonth(int year, int month) { return YearMonth.of(year, month).lengthOfMonth(); } public static String secToTime(String secondStr) { long second = new BigDecimal(secondStr).longValue(); long a = second / 3600; long b = second % 3600; long c = b / 60; long d = b % 60; return (a < 10 ? ("0" + a) : a) + ":" + (c < 10 ? ("0" + c) : c) + ":" + (d < 10 ? ("0" + d) : d); } public static String sec2Day(String secondStr) { long second = new BigDecimal(secondStr).longValue(); long a = second / (3600 * 24); long b = (second % (3600 * 24)) / 3600; return a + "天" + b + "小时"; } /** * <pre> * 获取环比时间 * </pre> * * @param startTime * @param endTime * @author sonin * @Description: TODO(这里描述这个方法的需求变更情况) */ public static String[] hbTime(String startTime, String endTime) { String hbStartTime = DateUtils.date2Str(DateUtils.prevMonth(DateUtils.strToDate(startTime, BaseConstant.dateFormat)), BaseConstant.dateFormat); String hbEndTime = DateUtils.date2Str(DateUtils.prevMonth(DateUtils.strToDate(endTime, BaseConstant.dateFormat)), BaseConstant.dateFormat); while (!hbStartTime.split("-")[1].equals(hbEndTime.split("-")[1])) { hbEndTime = DateUtils.date2Str(DateUtils.prevDay(DateUtils.strToDate(hbEndTime, BaseConstant.dateFormat)), BaseConstant.dateFormat); } return new String[]{hbStartTime, hbEndTime}; } /** * 同比 * @param month * @return */ public static String getTbMonth(String month) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); YearMonth yearMonth = YearMonth.parse(month, formatter); YearMonth sameMonthLastYear = yearMonth.minusYears(1); return sameMonthLastYear.format(formatter); // 同比 } /** * 环比 * @param month * @return */ public static String getHbMonth(String month) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); YearMonth yearMonth = YearMonth.parse(month, formatter); YearMonth previousMonth = yearMonth.minusMonths(1); return previousMonth.format(formatter); // 环比 } /*** * 环比年月 * @param dateStr yyyy-MM-dd * @return */ public static String getHbMonthDate(String dateStr) { // 定义日期格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); try { // 将日期字符串转换为LocalDate对象 LocalDate date = LocalDate.parse(dateStr, formatter); // 获取上个月的日期 LocalDate lastMonth = date.minusMonths(1); // 格式化上个月的日期为字符串 String lastMonthStr = lastMonth.format(formatter); // 打印结果 // System.out.println("原始日期: " + dateStr); // System.out.println("上个月的日期字符串: " + lastMonthStr); return lastMonthStr; } catch (Exception e) { System.out.println("日期字符串格式错误或解析失败: " + e.getMessage()); } return null; } /** * 获取同比时间 * @param date * @return */ public static String getTbDate(String date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Calendar calendar = Calendar.getInstance(); try{ Date dateTime = sdf.parse(date); calendar.setTime(dateTime); }catch (Exception e){ calendar.setTime(new Date()); } calendar.add(Calendar.YEAR, -1); Date preDate = calendar.getTime(); return sdf.format(preDate); } /** * 获取环比时间 * @param date * @return */ public static String getHbDate(String date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Calendar calendar = Calendar.getInstance(); try{ Date dateTime = sdf.parse(date); calendar.setTime(dateTime); }catch (Exception e){ calendar.setTime(new Date()); } calendar.add(Calendar.MONTH, -1); Date preDate = calendar.getTime(); return sdf.format(preDate); } /*** * 获取几个月之后日期 * @param month * @return */ public static String getDateByAfterMonth(int month) { // 设置日期格式 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); // 创建一个Calendar实例,并设置为当前日期和时间 Calendar calendar = Calendar.getInstance(); // 减去半年(6个月) //calendar.add(Calendar.MONTH, -6); calendar.add(Calendar.MONTH, month); // Date preDate = calendar.getTime(); // 获取半年前的日期 String afterDate = dateFormat.format(calendar.getTime()); return afterDate; } /** * 获取日期时间集合 * @param start * @param end * @return */ public static List<String> getDatesBetween(String start, String end) { List<String> dateList = new ArrayList<>(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate startDate = LocalDate.parse(start, formatter); LocalDate endDate = LocalDate.parse(end, formatter); if (!startDate.isAfter(endDate)) { LocalDate currentDate = startDate; while (!currentDate.isAfter(endDate)) { dateList.add(currentDate.toString()); currentDate = currentDate.plusDays(1); } } return dateList; } /** * 获取月份时间集合 * @param start * @param end * @return */ public static List<String> getMonthsBetween(String start, String end) { List<String> monthList = new ArrayList<>(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate startDate = LocalDate.parse(start, formatter); LocalDate endDate = LocalDate.parse(end, formatter); YearMonth startMonth = YearMonth.from(startDate); YearMonth endMonth = YearMonth.from(endDate); YearMonth currentMonth = startMonth; while (!currentMonth.isAfter(endMonth)) { monthList.add(currentMonth.toString()); currentMonth = currentMonth.plusMonths(1); } return monthList; } /*** * 获取当前年 * @return */ public static int getCurrentYear(){ Date currentDate = new Date(); Calendar calendar = Calendar.getInstance(); calendar.setTime(currentDate); return calendar.get(Calendar.YEAR); } /*** * 获取当前时间 * @return */ public static String getCurrentDate(){ LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedDate = now.format(formatter); return formattedDate; } public static int getDateYear(String date){ Date currentDate = str2Date(date,"yyyy-MM-dd"); Calendar calendar = Calendar.getInstance(); calendar.setTime(currentDate); return calendar.get(Calendar.YEAR); } public static int getDateMonth(String date){ Date currentDate = str2Date(date,"yyyy-MM-dd"); Calendar calendar = Calendar.getInstance(); calendar.setTime(currentDate); return calendar.get(Calendar.MONTH)+1; } }