package com.skua.tool.util; import com.skua.constant.BaseConstant; import java.math.BigDecimal; 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.util.*; /** * <pre> * 日期工具类 * </pre> * * @author sonin * @version 1.0 2022/4/20 17:22 */ public class DateUtils { /** * 根据(开始时间, 结束时间)获取每一个时间间隔的数据, 主要用于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 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); } }