package com.mmc.iuav.user.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 作者 geDuo
 * @version 创建时间：2021年7月17日 下午5:28:19
 * @explain 日期时间工具类
 */
public class TDateUtil {
    public static final String ONE_WEEK = "oneweek";
    public static final String ONE_MONTH = "onemonth";
    public static final String THREE_MONTH = "threemonth";
    public static final String SIX_MONTH = "sixmonth";
    public static final String ONE_YEAR = "oneyear";
    public static final String TYPE = "yyyyMMddHHmmss";

    public static String getCurrentDate() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm");// 设置日期格式
        String date = df.format(new Date());// new Date()为获取当前系统时间
        return date;
    }

    public static String getCurrentDateByType(String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);// 设置日期格式
        String date = df.format(new Date());// new Date()为获取当前系统时间
        return date;
    }

    public static String getCurrentDateMidd() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
        String date = df.format(new Date());// new Date()为获取当前系统时间
        return date;
    }

    public static Date getDate(String str, String format) {
        Date date = null;
        try {
            SimpleDateFormat df = new SimpleDateFormat(format);// 设置日期格式
            // String dates=df.format(new Date());// new Date()为获取当前系统时间
            date = df.parse(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * date类型转字符串
     */
    public static String getDateStr(Date date, String type) {
        SimpleDateFormat format = new SimpleDateFormat(type);
        String s = format.format(date);
        return s;
    }

    /**
     * 根据日期获得随机数
     */
    public static Integer getDateRandom(Date date, String format, int count) {
        String code = "";
        for (int i = 0; i < count; i++) {
            code = code + (int) (Math.random() * 9);
        }
        code = TDateUtil.getDateStr(date, format) + code;
        return Integer.parseInt(code);
    }

    /**
     * 10位数的秒转日期字符
     *
     * @param mss
     * @return
     */
    public static Date dateFromSecond(long sceondTime) {
        return new Date(sceondTime * 1000);
    }

    /**
     * 10位数的秒转日期字符
     *
     * @param mss
     * @return
     */
    public static String dateFromSecondStr(long sceondTime) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(sceondTime * 1000));
    }

    /**
     * 秒转时分秒
     *
     * @param secondTime
     * @return
     */
    public static String hmsFromSecond(Integer secondTime) {
        Integer hour = secondTime / 60 / 60;
        Integer minutes = secondTime / 60 % 60;
        Integer remainingSeconds = secondTime % 60;
        return (hour + "h" + minutes + "min" + remainingSeconds + "s");
    }

    public static String hmsFromSecondFormat(long secondTime) {
        long day = secondTime / 60 / 60 / 24;
        long hour = secondTime / 60 / 60 % 24;
        long minutes = secondTime / 60 % 60;
        long remainingSeconds = secondTime % 60;
        if (day > 0) {
            return (day + "天" + hour + "小时" + minutes + "分" + remainingSeconds + "秒");
        }
        return (hour + "小时" + minutes + "分" + remainingSeconds + "秒");
    }

    /**
     * 两个日期的相差秒数
     *
     * @param maxDate
     * @param minDate
     * @return
     */
    public static long calLastedTime(Date maxDate, Date minDate) {
        long a = maxDate.getTime();
        long b = minDate.getTime();
        long c = (a - b) / 1000;
        return c;
    }

    /**
     * 获取某个月的月底最后一天的时间
     */
    public static Date getMonthLatestDay(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        // 获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        String last = format.format(ca.getTime());
        Date dates = getDate(last, "yyyy-MM-dd");
        return dates;
    }

    /**
     * 某个时间 加N天
     */
    public static Date nextNumDay(Date d, int num) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            Date now = d;
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.add(Calendar.DAY_OF_MONTH, num);
            String last = format.format(calendar.getTime());
            date = getDate(last, "yyyy-MM-dd");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 某天个时间加 N 小时
     *
     * @param now
     * @param num
     * @return
     */
    public static Date addHourTime(Date now, int num) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.add(Calendar.HOUR, num);
            String last = format.format(calendar.getTime());
            date = getDate(last, "yyyy-MM-dd HH:mm:ss");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 某个时间加n个月加n天(负数为减)
     */
    @SuppressWarnings("static-access")
    public static Date getMonthNDayN(Date date, int month, int day) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date news = null;
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.MONTH, month);
            calendar.add(calendar.DATE, day);
            String last = format.format(calendar.getTime());
            news = getDate(last, "yyyy-MM-dd");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return news;
    }

    /**
     * 时间戳-计算小时
     */
    public static long getDistanceTime(long time1, long time2) {
        long diff = 0;
        long day = 0;
        long hour = 0;
        if (time1 < time2) {
            diff = time2 - time1;
        } else {
            diff = time1 - time2;
        }
        day = diff / (24 * 60 * 60 * 1000);
        hour = (diff / (60 * 60 * 1000) - day * 24);
        return hour;
    }

    /**
     * 两个时间之间相差距离多少天
     *
     * @param one 时间参数 1：
     * @param two 时间参数 2：
     * @return 相差天数
     */
    public static int distanceDays(Date one, Date two) {
        int days = 0;
        long time1 = one.getTime();
        long time2 = two.getTime();
        long diff;
        if (time1 < time2) {
            diff = time2 - time1;
        } else {
            diff = time1 - time2;
        }
        days = new Long(diff / (1000 * 60 * 60 * 24)).intValue();
        return days;
    }

    public static Date nextNumDateTime(Date d, int num) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            Date now = d;
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(now);
            calendar.add(Calendar.DAY_OF_MONTH, num);
            String last = format.format(calendar.getTime());
            date = getDate(last, "yyyy-MM-dd HH:mm:ss");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }

    public static String createYearWeek(String startStr, String endStr) {
        if (startStr == null || "".equals(startStr) || endStr == null || "".equals(endStr)) {
            return "起止日期不能为空";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date start = null;
        Date end = null;
        Date startDate;
        Date endDate;
        int dayOfWeek;
        boolean goOn = true;
        int no = 0;
        try {
            start = sdf.parse(startStr);
            end = sdf.parse(endStr);
        } catch (ParseException e) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            try {
                start = simpleDateFormat.parse(startStr);
                end = simpleDateFormat.parse(endStr);
            } catch (ParseException pe) {
                pe.printStackTrace();
            }
        }
        if (start.compareTo(end) > -1) {
            return "结束日期必须大于开始日期";
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        List<Map<String, String>> weekList = new ArrayList<>();
        if (dayOfWeek > 1 && dayOfWeek < 7) {
            do {
                startDate = start;
                calendar.add(Calendar.DATE, (8 - dayOfWeek));
                endDate = calendar.getTime();
                no += 1;
                Map<String, String> map = new HashMap<>();
                map.put("startOfWeek", sdf.format(startDate));
                map.put("weekNo", no + "");
                if (endDate.compareTo(end) < 0) {
                    map.put("endOfWeek", sdf.format(endDate));
                    weekList.add(map);
                    calendar.add(Calendar.DATE, 1);
                    start = calendar.getTime();
                    dayOfWeek = 2;
                } else {
                    map.put("endOfWeek", sdf.format(end));
                    weekList.add(map);
                    goOn = false;
                }
            } while (goOn);
        } else {
            no += 1;
            startDate = start;
            if (dayOfWeek == 1) {
                endDate = start;
            } else {
                calendar.add(Calendar.DATE, 1);
                endDate = calendar.getTime();
            }
            Map<String, String> map = new HashMap<>();
            map.put("startOfWeek", sdf.format(startDate));
            map.put("endOfWeek", sdf.format(endDate));
            map.put("weekNo", no + "");
            weekList.add(map);
            calendar.add(Calendar.DATE, 1);
            start = calendar.getTime();
            do {
                startDate = start;
                calendar.add(Calendar.DATE, 6);
                endDate = calendar.getTime();
                no += 1;
                map = new HashMap<>();
                map.put("startOfWeek", sdf.format(startDate));
                map.put("weekNo", no + "");
                if (endDate.compareTo(end) < 0) {
                    map.put("endOfWeek", sdf.format(endDate));
                    weekList.add(map);
                    calendar.add(Calendar.DATE, 1);
                    start = calendar.getTime();
                } else {
                    map.put("endOfWeek", sdf.format(end));
                    weekList.add(map);
                    goOn = false;
                }
            } while (goOn);
        }
        return weekList.toString();
    }

    /**
     * 获取起止日期
     *
     * @param sdf    需要显示的日期格式
     * @param date   需要参照的日期
     * @param n      最近n周
     * @param option 0 开始日期；1 结束日期
     * @param k      0 包含本周 1 不包含本周
     * @return
     */
    public static String getFromToDate(SimpleDateFormat sdf, Date date, int n, int option, int k) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        int offset = 0 == option ? 1 - dayOfWeek : 7 - dayOfWeek;
        int amount = 0 == option ? offset - (n - 1 + k) * 7 : offset - k * 7;
        calendar.add(Calendar.DATE, amount);
        return sdf.format(calendar.getTime());
    }

    /**
     * 根据当前日期获得最近n周的日期区间（包含本周）
     *
     * @param n
     * @param sdf
     * @return
     */
    public static String getNWeekTimeInterval(int n, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);// 设置日期格式
        String beginDate = getFromToDate(sdf, new Date(), n, 0, 0);
        String endDate = getFromToDate(sdf, new Date(), n, 1, 0);
        return beginDate + "," + endDate;
    }

    /**
     * 根据当前日期获得最近n周的日期区间（不包含本周）
     *
     * @param n
     * @param sdf
     * @return
     */
    public static String getNWeekTimeIntervalTwo(int n, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);// 设置日期格式
        String beginDate = getFromToDate(sdf, new Date(), n, 0, 1);
        String endDate = getFromToDate(sdf, new Date(), n, 1, 1);
        return beginDate + "," + endDate;
    }

    /**
     * 根据当前日期获得本周的日期区间（本周周一和周日日期）
     *
     * @param sdf
     * @return
     */
    public static String getThisWeekTimeInterval(String format) {
        return getNWeekTimeInterval(1, format);
    }

    /**
     * 根据当前日期获得上周的日期区间（上周周一和周日日期）
     *
     * @param sdf
     * @return
     */
    public static String getLastWeekTimeInterval(String format) {
        return getNWeekTimeIntervalTwo(1, format);
    }

    /**
     * 获取某个日期最近一个的星期日
     *
     * @return
     */
    public static Date getLatestWeekend(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        Date endDate = TDateUtil.nextNumDay(date, w * -1);
        return endDate;
    }

    /**
     * 获取N周的星期一的日期(正加负减)
     *
     * @param date
     * @return
     */
    public static Date getMinMonday(Date date, int weekNum) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        Date endDate = TDateUtil.nextNumDay(date, w * -1);
        Date startDate = TDateUtil.nextNumDay(endDate, (weekNum * 7) + 1);
        return startDate;
    }

    /**
     * 获取某个月加几个月后一号的日期
     */
    @SuppressWarnings("static-access")
    public static Date getAddMonThDay(Date date, int i) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendar.MONTH, i);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        String last = format.format(calendar.getTime());
        date = getDate(last, "yyyy-MM-dd");
        return date;
    }

    /**
     * 某个月最后一天
     */
    public static Date getAnyMonthLastDay(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        // 获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        String last = format.format(ca.getTime());
        date = getDate(last, "yyyy-MM-dd");
        return date;
    }

    public static Date getDate(Date date, String type) {
        SimpleDateFormat format = new SimpleDateFormat(type);
        String s = format.format(date);
        return getDate(s, type);
    }

    /**
     * 获取去年今天的日期
     */
    public static Date getLastYearTodayDate() {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.YEAR, -1);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String s = format.format(instance.getTime());
        return getDate(s, "yyyy-MM-dd");
    }

    /**
     * 获取昨天的日期
     *
     * @param type
     * @return
     */
    public static String getYesterdayDateByType(String type) {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DAY_OF_MONTH, -1);
        Date time = instance.getTime();
        SimpleDateFormat format = new SimpleDateFormat(type);
        return format.format(time);
    }

    /**
     * 判断两个时间是不是在同一个月
     */
    public static boolean isSameMonth(Date date1, Date date2) {

        Calendar c = Calendar.getInstance();
        c.setTime(date1);
        int month1 = c.get(Calendar.MONTH);
        c.setTime(date2);
        int month2 = c.get(Calendar.MONTH);
        if (month1 == month2) {
            return true;
        }
        return false;
    }

    /**
     * 间隔天数
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static int isolateDayNum(String startTime, String endTime) {
        Date startDate = getDate(startTime, "yyyy-MM-dd");
        Date endDate = getDate(endTime, "yyyy-MM-dd");
        long differentMillis = endDate.getTime() - startDate.getTime();
        long dayNum = differentMillis / (1000 * 60 * 60 * 24);
        return (int) dayNum;
    }

    /**
     * 获取某月最后一天的时间
     *
     * @param yearMonth
     * @return
     */
    public static String getLastDateTimeOfMonth(String yearMonth) {
        SimpleDateFormat format0 = new SimpleDateFormat("yyyy-MM");
        SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar instance = Calendar.getInstance();
        try {
            Date parse = format0.parse(yearMonth);
            instance.setTime(parse);
            instance.set(Calendar.DAY_OF_MONTH, instance.getActualMaximum(Calendar.DAY_OF_MONTH));
            instance.set(Calendar.HOUR_OF_DAY, 23);
            instance.set(Calendar.MINUTE, 59);
            instance.set(Calendar.SECOND, 59);
            String format = format1.format(instance.getTime());
            return format;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date getStrToDate(String str) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        Date date = null;
        try {
            if (str == null) {
                date = null;
            } else {
                date = dateFormat.parse(str);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    public static int getStageByDate(Date date) {
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        //当前时间
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
        String format = dateFormat.format(date);
        try {
            Date currentTime = dateFormat.parse(format);

            Date parse1 = dateFormat.parse("05:00:00");
            Date parse2 = dateFormat.parse("11:00:00");

            Date parse3 = dateFormat.parse("17:00:00");
            Date parse4 = dateFormat.parse("00:00:00");

            //A:05:00-11:00 | B:11:00-17:00 | C:00:00-05:00,17:00-00:00
            if (currentTime.after(parse4) && currentTime.before(parse1)) {
                return 3;
            } else if (currentTime.after(parse1) && currentTime.before(parse2)) {
                return 1;
            } else if (currentTime.after(parse2) && currentTime.before(parse3)) {
                return 2;
            } else if (currentTime.after(parse3) && currentTime.after(parse4)) {
                return 4;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static String getCurrentYear() {
        Calendar date = Calendar.getInstance();
        String year = String.valueOf(date.get(Calendar.YEAR));
        return year;
    }
}
