package com.dxhy.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author jiaohongyang
 */
@Slf4j
@SuppressWarnings({"AlibabaLowerCamelCaseVariableNaming", "AlibabaUndefineMagicConstant"})
public class DateUtils {

    private static String dateFormat_yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
    private static ThreadLocal<SimpleDateFormat> simpleDateFormat_yyyymm = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMM"));
    private static ThreadLocal<SimpleDateFormat> simpleDateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd"));


    /**
     * 获取现在时间,这个好用
     *
     * 返回长时间格式 yyyy-MM-dd HH:mm:ss
     */
    public static Date getSqlDate() {
        return new java.sql.Date(System.currentTimeMillis());
    }

    /**
     * 获取现在时间
     *
     * 返回长时间格式 yyyy-MM-dd HH:mm:ss
     */
    public static Date getSqlDateLong() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(currentTime);
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(dateString, pos);
    }

    /**
     * 获取现在时间
     *
     * 返回长时间格式 yyyy-MM-dd HH:mm:ss
     */
    public static Date getNowDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(currentTime);
        ParsePosition pos = new ParsePosition(8);
        return formatter.parse(dateString, pos);
    }

    /**
     * 获取现在时间
     *
     * 返回短时间格式 yyyy-MM-dd
     */
    public static Date getNowDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(currentTime);
        ParsePosition pos = new ParsePosition(8);
        return formatter.parse(dateString, pos);
    }

    /**
     * 获取现在时间
     *
     * 返回字符串格式 yyyy-MM-dd HH:mm:ss
     */
    public static String getStringDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return formatter.format(currentTime);
    }

    /**
     * 获取现在时间
     *
     * 返回短时间字符串格式yyyy-MM-dd
     */
    public static String getStringDateShort() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return formatter.format(currentTime);
    }

    /**
     * 获取时间 小时:分;秒 HH:mm:ss
     *
     *
     */
    public static String getTimeShort() {
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
        Date currentTime = new Date();
        return formatter.format(currentTime);
    }

    /**
     * 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
     *
     * @param strDate
     *            日期
     *
     */
    public static Date strToDateLong(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss
     *
     * @param dateDate
     *            日期
     *
     */
    public static String dateToStrLong(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return formatter.format(dateDate);
    }

    /**
     * 将短时间格式时间转换为字符串 yyyy-MM-dd
     *
     * @param dateDate
     *            日期
     *
     */
    public static String dateToStr(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        return formatter.format(dateDate);
    }

    /**
     * @Description 格式化日期为字符串
     * @Return java.lang.String
     * @Author wangruwei
     * @Date 2022/11/15 11:40
     **/
    public static String dateToStr(java.util.Date dateDate,String format) {
        if (dateDate == null) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(dateDate);
    }

    /**
     * 日期格式化到月份
     *
     * @param dateDate
     *            日期
     *
     */
    public static String dateToMonthStr(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");
        return formatter.format(dateDate);
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd
     *
     * @param strDate
     *            日期
     *
     */
    public static Date strToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * @Description 字符串类型的日期转为date,字符串和格式长度需一样
     * @Return java.lang.String
     * @Author wangruwei
     * @Date 2022/11/15 11:40
     **/
    public static Date strToDate(String strDate,String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * 获取当前日期的前n个月
     */
    public static String getDateByMonth(int n) throws ParseException {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - n);
        String format = simpleDateFormat.get().format(cal.getTime());
        return format;
    }

    /**
     * 根据传入的整数对当前日期进行月份的偏移，并返回指定格式（yyyy-MM）的日期字符串
     *
     * @param n 要偏移的月份数，正数表示往后推，负数表示往前推
     * @return 偏移后的日期字符串，格式为 yyyy-MM
     */
    public static String getMonthByMonth(int n) {
        LocalDate currentDate = LocalDate.now();
        LocalDate shiftedDate = currentDate.plusMonths(n);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        return shiftedDate.format(formatter);
    }

    /**
    * @Description 获取n年之前之后的日期  正数之后；负数之前
    * @param n
    * @Return java.lang.String
    * @Author wangruwei
    * @Date 2024/10/21 16:34
    **/
    public static String getDateByYear(int n) throws ParseException {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR,cal.get(Calendar.YEAR) + n);
        String format = simpleDateFormat.get().format(cal.getTime());
        return format;
    }

    /**
    * @Description 获取n年前(后)的1月1日 2024年传入-2 得到20220101
    * @param n
    * @Return java.lang.String
    * @Author wangruwei
    * @Date 2024/10/21 16:42
    **/
    public static String getDateByYearFirst(int n) throws ParseException {
        return getYearStart( getDateByYear(n));
    }

    /**
     * @param strDate
     *            日期
     *
     */
    public static Date strToDateChina(String strDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        ParsePosition pos = new ParsePosition(0);
        return sdf.parse(strDate, pos);
    }



    /**
     * 把yyyy-MM-dd格式的日期字符串转化为yyyy年MM月dd日返回
     **/
    public static String strToStrChina(String inputDate) {
        // 定义输入和输出的日期格式
        SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy年MM月dd日");

        String formattedDate = null;
        try {
            // 将输入日期字符串解析为 Date 对象
            Date date = inputFormat.parse(inputDate);
            // 将 Date 对象格式化为输出字符串
            formattedDate = outputFormat.format(date);
        } catch (ParseException e) {
            log.error("格式化日期出错:{}",e);
        }

        return formattedDate;
    }

    /**
     * 得到现在时间
     *
     *
     */
    public static Date getNow() {
        return new Date();
    }

    /**
     * 提取一个月中的最后一天
     *
     * @param day
     *            日期
     *
     */
    public static Date getLastDate(long day) {
        Date date = new Date();
        long date3Hm = date.getTime() - 3600000 * 34 * day;
        return new Date(date3Hm);
    }

    /**
     * 得到现在时间
     *
     * 字符串 yyyyMMdd HHmmss
     */
    public static String getStringToday() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd HHmmss");
        return formatter.format(currentTime);
    }

    /**
     * 得到现在小时
     */
    public static String getHour() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(currentTime);
        String hour;
        hour = dateString.substring(11, 13);
        return hour;
    }

    /**
     * 得到现在分钟
     *
     *
     */
    public static String getTime() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(currentTime);
        String min;
        min = dateString.substring(14, 16);
        return min;
    }

    /**
     * 根据用户传入的时间表示格式，返回当前时间的格式 如果是yyyyMMdd，注意字母y不能大写。
     *
     * @param sformat
     *            yyyyMMddhhmmss
     *
     */
    public static String getUserDate(String sformat) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(sformat);
        return formatter.format(currentTime);
    }

    /**
     * 二个小时时间间的差值,必须保证二个时间都是"HH:MM"的格式，返回字符型的分钟
     */
    public static String getTwoHour(String st1, String st2) {
        String[] kk;
        String[] jj;
        kk = st1.split(":");
        jj = st2.split(":");
        if (Integer.parseInt(kk[0]) < Integer.parseInt(jj[0])) {
            return "0";
        } else {
            double y = Double.parseDouble(kk[0]) + Double.parseDouble(kk[1]) / 60;
            double u = Double.parseDouble(jj[0]) + Double.parseDouble(jj[1]) / 60;
            if ((y - u) > 0) {
                return y - u + "";
            } else {
                return "0";
            }
        }
    }

    /**
     * 得到二个日期间的间隔天数
     */
    public static String getTwoDay(String sj1, String sj2) {
        SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
        long day;
        try {
            java.util.Date date = myFormatter.parse(sj1);
            java.util.Date mydate = myFormatter.parse(sj2);
            day = (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
        } catch (Exception e) {
            return "";
        }
        return day + "";
    }

    /**
     * 时间前推或后推分钟,其中JJ表示分钟.
     */
    public static String getPreTime(String sj1, String jj) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String mydate1 = "";
        try {
            Date date1 = format.parse(sj1);
            long time = (date1.getTime() / 1000) + Integer.parseInt(jj) * 60;
            date1.setTime(time * 1000);
            mydate1 = format.format(date1);
        } catch (Exception ignored) {
        }
        return mydate1;
    }

    /**
     * 得到一个时间延后或前移几天的时间,nowdate为时间,delay为前移或后延的天数
     *
     * @param nowdate
     *            日期
     * @param delay
     *            日期
     */
    public static String getNextDay(String nowdate, String delay) {
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            String mdate;
            Date d = strToDate(nowdate);
            long myTime = (d.getTime() / 1000) + Integer.parseInt(delay) * 24 * 60 * 60;
            d.setTime(myTime * 1000);
            mdate = format.format(d);
            return mdate;
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 判断是否润年 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年 3.能被4整除同时能被100整除则不是闰年
     *
     * @param ddate
     *            日期
     *
     */
    public static boolean isLeapYear(String ddate) {

        Date d = strToDate(ddate);
        GregorianCalendar gc = (GregorianCalendar)Calendar.getInstance();
        gc.setTime(d);
        int year = gc.get(Calendar.YEAR);
        if ((year % 400) == 0) {
            return true;
        } else if ((year % 4) == 0) {
            return (year % 100) != 0;
        } else {
            return false;
        }
    }

    /**
     * 返回美国时间格式 26 Apr 2006
     *
     * @param str
     *            日期
     *
     */
    public static String getEDate(String str) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(str, pos);
        String j = strtodate.toString();
        String[] k = j.split(" ");
        return k[2] + k[1].toUpperCase() + k[5].substring(2, 4);
    }

    /**
     * 获取一个月的最后一天
     *
     * @param dat
     *            日期
     *
     */
    public static String getEndDateOfMonth(String dat) {
        String str = dat.substring(0, 8);
        String month = dat.substring(5, 7);
        int mon = Integer.parseInt(month);
        if (mon == 1 || mon == 3 || mon == 5 || mon == 7 || mon == 8 || mon == 10 || mon == 12) {
            str += "31";
        } else if (mon == 4 || mon == 6 || mon == 9 || mon == 11) {
            str += "30";
        } else {
            if (isLeapYear(dat)) {
                str += "29";
            } else {
                str += "28";
            }
        }
        return str;
    }

    /**
     * 判断二个时间是否在同一个周
     *
     * @param date1
     *            日期
     * @param date2
     *            日期
     *
     */
    public static boolean isSameWeekDates(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(date1);
        cal2.setTime(date2);
        int subYear = cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR);
        if (0 == subYear) {
            return cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR);
        } else if (1 == subYear && Calendar.DECEMBER == cal2.get(Calendar.MONTH)) {
            // 如果12月的最后一周横跨来年第一周的话则最后一周即算做来年的第一周
            return cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR);
        } else if (-1 == subYear && Calendar.DECEMBER == cal1.get(Calendar.MONTH)) {
            return cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR);
        }
        return false;
    }

    /**
     * 产生周序列,即得到当前时间所在的年度是第几周
     *
     *
     */
    public static String getSeqWeek() {
        Calendar c = Calendar.getInstance(Locale.CHINA);
        String week = Integer.toString(c.get(Calendar.WEEK_OF_YEAR));
        if (week.length() == 1) {
            week = "0" + week;
        }
        String year = Integer.toString(c.get(Calendar.YEAR));
        return year + week;
    }

    /**
     * 获得一个日期所在的周的星期几的日期，如要找出2002年2月3日所在周的星期一是几号
     *
     * @param sdate
     *            日期
     * @param num
     *            星期
     *
     */
    public static String getWeek(String sdate, String num) {
        // 再转换为时间
        Date dd = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(dd);
        // 返回星期一所在的日期
        if ("1".equals(num)) {
            c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            // 返回星期二所在的日期
        } else if ("2".equals(num)) {
            c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
        } else if ("3".equals(num)) {
            c.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
        } else if ("4".equals(num)) {
            c.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
        } else if ("5".equals(num)) {
            c.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
        } else if ("6".equals(num)) {
            c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
        } else if ("0".equals(num)) {
            c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        }
        return new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());
    }

    /**
     * 根据一个日期，返回是星期几的字符串
     *
     * @param sdate
     *            日期
     *
     */
    public static String getWeek(String sdate) {
        // 再转换为时间
        Date date = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // hour中存的就是星期几了，其范围 1~7
        return new SimpleDateFormat("EEEE").format(c.getTime());
    }

    public static String getWeekStr(String sdate) {
        String str;
        str = getWeek(sdate);
        switch (str) {
            case "1":
                str = "星期日";
                break;
            case "2":
                str = "星期一";
                break;
            case "3":
                str = "星期二";
                break;
            case "4":
                str = "星期三";
                break;
            case "5":
                str = "星期四";
                break;
            case "6":
                str = "星期五";
                break;
            case "7":
                str = "星期六";
                break;
            default:
                break;
        }
        return str;
    }

    /**
     * 两个时间之间的天数
     *
     * @param date1
     *            日期
     * @param date2
     *            日期
     *
     */
    public static long getDays(String date1, String date2) {
        if (date1 == null || "".equals(date1)) {
            return 0;
        }
        if (date2 == null || "".equals(date2)) {
            return 0;
        }
        // 转换为标准时间
        SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
        java.util.Date date = null;
        java.util.Date mydate = null;
        try {
            date = myFormatter.parse(date1);
            mydate = myFormatter.parse(date2);
        } catch (Exception ignored) {
        }
        assert mydate != null;
        return (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
    }

    /**
     * 形成如下的日历 ， 根据传入的一个时间返回一个结构 星期日 星期一 星期二 星期三 星期四 星期五 星期六 下面是当月的各个时间 此函数返回该日历第一行星期日所在的日期
     *
     * @param sdate
     *            日期
     *
     */
    public static String getNowMonth(String sdate) {
        // 取该时间所在月的一号
        sdate = sdate.substring(0, 8) + "01";
        // 得到这个月的1号是星期几
        Date date = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int u = c.get(Calendar.DAY_OF_WEEK);
        return getNextDay(sdate, (1 - u) + "");
    }

    /**
    * @Description 获取当前月的时间格式，返回 yyyy-MM
    * @param
    * @Return java.lang.String
    * @Author wangruwei
    * @Date 2024/6/5 10:05
    **/
    public static String getNowMonthStr() {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");

        // 格式化当前日期为 yyyy-MM 格式的字符串
        String formattedDate = currentDate.format(formatter);

        return formattedDate;
    }

    /**
     * 取得数据库主键 生成格式为yyyymmddhhmmss+k位随机数
     *
     * @param k
     *            表示是取几位随机数，可以自己定
     */
    public static String getNo(int k) {
        return getUserDate("yyyyMMddhhmmss") + getRandom(k);
    }

    /**
     * 返回一个随机数
     *
     * @param i
     *            随机数
     *
     */
    public static String getRandom(int i) {
        Random jjj = new Random();
        if (i == 0) {
            return "";
        }
        StringBuilder jj = new StringBuilder();
        for (int k = 0; k < i; k++) {
            jj.append(jjj.nextInt(9));
        }
        return jj.toString();
    }

    /**
     * @param date
     *            日期
     */
    public static boolean RightDate(String date) {
        SimpleDateFormat sdf;;
        if (date == null) {
            return true;
        }
        if (date.length() > 10) {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        } else {
            sdf = new SimpleDateFormat("yyyy-MM-dd");
        }
        try {
            sdf.parse(date);
        } catch (ParseException pe) {
            return true;
        }
        return false;
    }

    /**
     * //nd=1表示返回的值中包含年度 //yf=1表示返回的值中包含月份 //rq=1表示返回的值中包含日期 //format表示返回的格式 1 以年月日中文返回 2 以横线-返回 // 3 以斜线/返回 4
     * 以缩写不带其它符号形式返回 // 5 以点号.返回
     */
    public static String getStringDateMonth(String sdate, String nd, String yf, String rq, String format) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(currentTime);
        // 年份
        String s_nd = dateString.substring(0, 4);
        // 月份
        String s_yf = dateString.substring(5, 7);
        // 日期
        String s_rq = dateString.substring(8, 10);
        String sreturn = "";
        // 处理空值情况
        if (sdate == null || "".equals(sdate) || RightDate(sdate)) {
            if ("1".equals(nd)) {
                sreturn = s_nd;
                // 处理间隔符
                if ("1".equals(format)) {
                    sreturn = sreturn + "年";
                } else if ("2".equals(format)) {
                    sreturn = sreturn + "-";
                } else if ("3".equals(format)) {
                    sreturn = sreturn + "/";
                } else if ("5".equals(format)) {
                    sreturn = sreturn + ".";
                }
            }
            // 处理月份
            if ("1".equals(yf)) {
                sreturn = sreturn + s_yf;
                if ("1".equals(format)) {
                    sreturn = sreturn + "月";
                } else if ("2".equals(format)) {
                    sreturn = sreturn + "-";
                } else if ("3".equals(format)) {
                    sreturn = sreturn + "/";
                } else if ("5".equals(format)) {
                    sreturn = sreturn + ".";
                }
            }
            // 处理日期
            if ("1".equals(rq)) {
                sreturn = sreturn + s_rq;
                if ("1".equals(format)) {
                    sreturn = sreturn + "日";
                }
            }
        } else {
            // 不是空值，也是一个合法的日期值，则先将其转换为标准的时间格式
            // 年份
            s_nd = sdate.substring(0, 4);
            // 月份
            s_yf = sdate.substring(5, 7);
            // 日期
            s_rq = sdate.substring(8, 10);
            if ("1".equals(nd)) {
                sreturn = s_nd;
                // 处理间隔符
                if ("1".equals(format)) {
                    sreturn = sreturn + "年";
                } else if ("2".equals(format)) {
                    sreturn = sreturn + "-";
                } else if ("3".equals(format)) {
                    sreturn = sreturn + "/";
                } else if ("5".equals(format)) {
                    sreturn = sreturn + ".";
                }
            }
            // 处理月份
            if ("1".equals(yf)) {
                sreturn = sreturn + s_yf;
                if ("1".equals(format)) {
                    sreturn = sreturn + "月";
                } else if ("2".equals(format)) {
                    sreturn = sreturn + "-";
                } else if ("3".equals(format)) {
                    sreturn = sreturn + "/";
                } else if ("5".equals(format)) {
                    sreturn = sreturn + ".";
                }
            }
            // 处理日期
            if ("1".equals(rq)) {
                sreturn = sreturn + s_rq;
                if ("1".equals(format)) {
                    sreturn = sreturn + "日";
                }
            }
        }
        return sreturn;
    }

    public static String getNextMonthDay(String sdate, int m) {
        sdate = getOKDate(sdate);
        int year = Integer.parseInt(sdate.substring(0, 4));
        int month = Integer.parseInt(sdate.substring(5, 7));
        String day = sdate.substring(8, 10);
        month = month + m;
        if (month < 0) {
            month = month + 12;
            year = year - 1;
        } else if (month > 12) {
            month = month - 12;
            year = year + 1;
        }
        String smonth = "";
        if (month < 10) {
            smonth = "0" + month;
        } else {
            smonth = "" + month;
        }
        return year + "-" + smonth + "-" + day;
    }

    public static String getOKDate(String sdate) {
        if (sdate == null || "".equals(sdate)) {
            return getStringDateShort();
        }
        if (RightDate(sdate)) {
            sdate = getStringDateShort();
        }
        // 将“/”转换为“-”
        sdate = sdate.replace("/", "-");
        // 如果只有8位长度，则要进行转换
        if (sdate.length() == 8) {
            sdate = sdate.substring(0, 4) + "-" + sdate.substring(4, 6) + "-" + sdate.substring(6, 8);
        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(sdate, pos);
        return formatter.format(strtodate);
    }

    /**
     * 获取某年第一天日期
     *
     * @param year
     *            年份 Date
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 获取某年最后一天日期
     *
     * @param year
     *            年份 Date
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);

        return calendar.getTime();
    }

    /**
     * 将短时间格式时间转换为字符串 yyyy-MM-dd
     *
     *
     */
    public static String getNowYyyyMmDd() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
        return formatter.format(new Date());
    }

    /**
     * 格式化时间为 yyyy-MM-dd 00:00:00
     *
     *
     * @throws ParseException
     */
    public static String getMorning(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 格式化时间为 yyyy-MM-dd 23:59:59
     *
     * @param date
     *
     */
    public static String getNight(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 属期相关日期没-
     *
     * @param strDate
     *
     */
    public static Date strToDatePeriod(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
    * @Description 日期转化，指定格式
    * @param strDate
    * @param format
    * @Return java.util.Date
    * @Author wangruwei
    * @Date 2024/8/2 10:37
    **/
    public static Date strToDatePeriodFormate(String strDate,String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        ParsePosition pos = new ParsePosition(0);
        return formatter.parse(strDate, pos);
    }

    /**
     * yyyyMMdd ת yyyy-MM-dd
     *
     * @param strDate
     *
     */
    public static String strToStrDate(String strDate) {
        String strtostr = "";
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat formatter2 = new SimpleDateFormat("yyyyMMdd");
            Date date = formatter2.parse(strDate);
            strtostr = formatter.format(date);
        } catch (ParseException e) {
           log.info("业务处理异常：{}", e);
        }
        return strtostr;
    }

    /**
     * yyyy-MM-dd ת yyyyMMdd
     *
     * @param strDate
     *
     */
    public static String strToStrDate2(String strDate) {
        String strtostr = "";
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat formatter2 = new SimpleDateFormat("yyyyMMdd");
            Date date = formatter.parse(strDate);
            strtostr = formatter2.format(date);
        } catch (ParseException e) {
           log.info("业务处理异常：{}", e);
        }
        return strtostr;
    }

    public static String getNowTimeStamp() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return formatter.format(currentTime);
    }

    /**
     * @Description 获取所传日期到当前日期的所有月的开始日期结束日期集合
     * 今日20221115，传入20221003，返回
     * [20221001@20221031, 20221101@20221130]
     * @Return java.util.List<java.lang.String>
     * @Author wangruwei
     * @Date 2022/11/23 10:08
     **/
    public static List<String> getStarToNowMonth(Date startDate) throws ParseException {
        List<String> list = new LinkedList<String>();
        String starStr = dateToStr(startDate, "yyyyMM");
        String nowStr = dateToStr(new Date(), "yyyyMM");
        //如果当前月大于等于开始月
        String startrq = starStr+"01";
        if(nowStr.compareTo(starStr)>=0){
            list.add(getMonthStart(startrq)+"@"+getMonthEndyyyyMMdd(startrq));

            while (true){
                //如果这个月是当前月，在上述已经入list，跳出
                boolean isThisMonth = isThisTime(startrq);
                if(isThisMonth){
                    break;
                }
                String nextMonth = addMonth(startrq);
                startrq = nextMonth;

                list.add(getMonthStart(startrq)+"@"+getMonthEndyyyyMMdd(startrq));
                //如果下个月大于这个月，跳出
                if(nextMonth.compareTo(nowStr)>0){
                    break;
                }
            }
        }
        return list;
    }

    /**
     * @Description 根据月份切割时间
     * @return 2022-11-23 00:00:00@2022-11-30 23:59:59, 2022-12-01 00:00:00@2022-12-31 23:59:59
     **/
    public static List<String> splitDateByMonth(Date startDate,Date endDate){
        List<String> list = new LinkedList<String>();
            while (true){
                if (startDate.compareTo(endDate) <= 0) {
                    //判断是否是同一个月
                    if (isSameYearsAndMonth(startDate, endDate)) {
                        list.add(getStartDateTime(startDate) + "@" + getEndDateTime(endDate));
                        break;
                    } else {
                        list.add(getStartDateTime(startDate) + "@" + getEndDateTime(getMonthLastDay(startDate)));
                        startDate = getNextMonthFirstDay(startDate);
                    }
                } else {
                    break;
                }
        }
        return list;
    }


    /**
     * @description  获取月的第一天
     * @author  Allen
     * @date    2024/5/11 14:06
     * @return
     */
    private static Date getNextMonthFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH,1);
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * @description  获取月的最后一天
     * @author  Allen
     * @date    2024/5/11 14:06
     * @return
    */
    private static Date getMonthLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 获取每天的开始时间
     * @param startDate
     * @return 开始时间 yyyy-MM-dd HH:mm:ss
     */
    private static String getStartDateTime(Date startDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return dateToStr(calendar.getTime(),dateFormat_yyyyMMddHHmmss);
    }

    /**
     * 获取每天的结束时间
     * @param endDate
     * @return 结束时间 yyyy-MM-dd HH:mm:ss
     */
    private static String getEndDateTime(Date endDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return dateToStr(calendar.getTime(),dateFormat_yyyyMMddHHmmss);
    }

    /**
     * 当前日期月份加 1
     * @param month 格式为yyyyMMdd
     * @return
     * @throws ParseException
     */
    public static String addMonth(String month) throws ParseException {
        Calendar cld = Calendar.getInstance();
        cld.setTime(simpleDateFormat.get().parse(month));
        cld.add(Calendar.MONTH, +1);
        return simpleDateFormat.get().format(cld.getTime());
    }

    /**
     *  获取某一个日期该月第一天
     * @param StartTime 格式为yyyyMMdd
     * @return
     * @throws ParseException
     */
    public static String getMonthStart(String StartTime) throws ParseException {
        Date date = simpleDateFormat.get().parse(StartTime);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);//设置为1号
        String format = simpleDateFormat.get().format(cal.getTime());
        return format;
    }

    /**
     *  获取某一个年的1月1日
     * @param StartTime 格式为yyyyMMdd
     * @return
     * @throws ParseException
     */
    public static String getYearStart(String StartTime) throws ParseException {
        Date date = simpleDateFormat.get().parse(StartTime);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, 0);//设置为1月
        cal.set(Calendar.DAY_OF_MONTH, 1);//设置为1号
        String format = simpleDateFormat.get().format(cal.getTime());
        return format;
    }

    /**
     * 获取某一个日期该月最后一天
     * @param endTime 格式为yyyyMMdd
     * @return
     * @throws ParseException
     */
    public static String getMonthEndyyyyMMdd(String endTime) throws ParseException {
        Date date = simpleDateFormat.get().parse(endTime);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        String format = simpleDateFormat.get().format(cal.getTime());
        return format;
    }

    /**
     * 判断当前日期是否为当前月yyyyMMdd
     */
    public static boolean isThisTime(String endTime) throws ParseException {
        Date date = simpleDateFormat.get().parse(endTime);
        String param = simpleDateFormat_yyyymm.get().format(date);//参数时间
        String now = simpleDateFormat_yyyymm.get().format(new Date());//当前时间
        if (param.equals(now)) {
            return true;
        }
        return false;
    }


    /**
     * 判断日期是否为当前月
     */
    public static boolean isThisTime(Date time){
        String param = simpleDateFormat_yyyymm.get().format(time);//参数时间
        String now = simpleDateFormat_yyyymm.get().format(new Date());//当前时间
        if (param.equals(now)) {
            return true;
        }
        return false;
    }



    /**
     * 判断两个日期是否是同一个月
     */
    public static boolean isSameYearsAndMonth(Date time1,Date time2){
        String param = simpleDateFormat_yyyymm.get().format(time1);//参数时间
        String now = simpleDateFormat_yyyymm.get().format(time2);//当前时间
        if (param.equals(now)) {
            return true;
        }
        return false;
    }

    /**
     * 判断日期是否符合指定日期格式 符合返回true，不符合返回false
     **/
    public static boolean checkStrFormat(String dateStr,String format){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setLenient(false);

        try {
            Date date = sdf.parse(dateStr);
            // 比较解析后的日期字符串与原始输入字符串
            String formattedDate = sdf.format(date);
            return formattedDate.equals(dateStr);
        } catch (Exception e) {
            return false;
        }
    }

    public static void main(String[] args) throws ParseException {
        //System.out.println(checkStrFormat("2024-01","yyyy-MM"));
        //System.out.println(checkStrFormat("2024-13","yyyy-MM"));
        //System.out.println(checkStrFormat("2024-01-02","yyyy-MM"));
        //System.out.println(getNowMonthStr());
        //
        //System.out.println(Integer.parseInt("2024-01".replace("-", "")) > Integer.parseInt(DateUtils.getNowMonthStr().replace("-", "")));
        //System.out.println(Integer.parseInt("2024-06".replace("-", "")) > Integer.parseInt(DateUtils.getNowMonthStr().replace("-", "")));
        //System.out.println(Integer.parseInt("2024-07".replace("-", "")) > Integer.parseInt(DateUtils.getNowMonthStr().replace("-", "")));
        //
        //System.out.println(dateToStr(new Date(), "yyyy-MM"));
        System.out.println(getStarToNowMonth(new Date()));

        System.out.println(getMonthStart("20240121"));

        System.out.println(getDateByYearFirst(-2));

        System.out.println(getYearStart("20241021"));
        System.out.println(getNowMonthStr());
        System.out.println(getMonthByMonth(6));
        System.out.println(getMonthByMonth(-6));
    }

    /**
     * 时间前推或后推分钟,其中JJ表示分钟.
     */
    public static Date timeAdd(Date sj1, int jj) {
        long time = (sj1.getTime() / 1000) + jj * 60;
        sj1.setTime(time * 1000);
        return sj1;
    }
}
