package cn.hnthyy.thmz.Utils;

import cn.hnthyy.thmz.entity.MzException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期工具类
 */
@Slf4j
public class DateUtil {
    /**
     * 判断给定时间与当前时间间隔小时数是否满足给定的间隔小时数
     *
     * @param startTime
     * @param intervalTime
     * @return
     */
    public static boolean intervalTime(Date startTime, int intervalTime) {
        if (startTime == null) {
            return true;
        }
        long cha = System.currentTimeMillis() - startTime.getTime();
        double result = cha * 1.0 / (1000 * 60 * 60);
        if (result <= intervalTime) {
            return false; //说明小于给定的小时数
        } else {
            return true;
        }
    }

    /**
     * 获取与当前时间相隔多少个分钟后的时间
     *
     * @param minutes 间隔分钟数
     * @return
     */
    public static Date getMinuteAfterDate(int minutes) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, minutes);
        return calendar.getTime();
    }

    /**
     * 获取与当前时间相隔多少个小时数后的时间
     *
     * @param time 间隔小时数
     * @return
     */
    public static Date getDate(int time) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR, time);
        return calendar.getTime();
    }

    /**
     * 将日期转换成相应格式字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String paseToString(Date date, String format) {
        if (date != null && StringUtils.isNotBlank(format)) {
            DateFormat sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        }
        return null;
    }

    /**
     * 获取昨天的0点0分0秒
     *
     * @return
     */
    public static Date getPrevDayFirstSecond() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取当前日期的0点0分0秒
     *
     * @return
     */
    public static Date getFirstSecond() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取给定日期的0点0分0秒
     *
     * @return
     */
    public static Date getFirstSecond(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }


    /**
     * 获取给定日期的23点59分59秒
     *
     * @return
     */
    public static Date getLastSecond(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 转换时间
     *
     * @param time
     * @param format
     * @return
     */
    public static Date pase(String time, String format) {
        if (StringUtils.isBlank(time) || StringUtils.isBlank(format)) {
            return null;
        }
        SimpleDateFormat smf = new SimpleDateFormat(format);
        try {
            return smf.parse(time);
        } catch (ParseException e) {
            return null;
        }
    }


    /**
     * 转换时间
     *
     * @param time
     * @param format
     * @return
     */
    public static Date pase(Date time, String format) {
        if (time == null || StringUtils.isBlank(format)) {
            return null;
        }
        SimpleDateFormat smf = new SimpleDateFormat(format);
        try {
            return smf.parse(smf.format(time));
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 转换时间
     *
     * @param time
     * @param format
     * @return
     */
    public static String fomart(Date time, String format) {
        if (time == null || StringUtils.isBlank(format)) {
            return null;
        }
        SimpleDateFormat smf = new SimpleDateFormat(format);
        return smf.format(time);
    }

    /**
     * 根据给定日期获取给定日期当月的第一天的0点0分0秒
     *
     * @return
     */
    public static Date getFirstSecondForMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }


    /**
     * 获取两个日期之间的所有日期集合
     *
     * @param start
     * @param end
     * @return
     */
    public static List<Date> getBetweenDates(Date start, Date end) {
        List<Date> result = new ArrayList<>();
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);
        tempStart.add(Calendar.DAY_OF_YEAR, 1);

        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);
        result.add(start);
        while (tempStart.before(tempEnd)) {
            result.add(tempStart.getTime());
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }
        if (!result.contains(end)) {
            result.add(end);
        }
        return result;
    }


    /**
     * 获取两个日期之间的所有日期集合 字符串类型
     *
     * @param start
     * @param end
     * @return
     */
    public static List<String> getBetweenDatesDesc(Date start, Date end) {
        List<String> result = new ArrayList<>();
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);
        tempStart.add(Calendar.DAY_OF_YEAR, 1);

        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);
        result.add(DateFormatUtils.format(start, "yyyy-MM-dd"));
        while (tempStart.before(tempEnd)) {
            result.add(DateFormatUtils.format(tempStart.getTime(), "yyyy-MM-dd"));
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }
        String endStr = DateFormatUtils.format(end, "yyyy-MM-dd");
        if (!result.contains(endStr)) {
            result.add(endStr);
        }
        return result;
    }

    /**
     * 判断是否是中午
     *
     * @param currentTime
     * @return
     */
    public static int IsAfternoon(int currentTime) {
        return currentTime - 12;
    }


    /**
     * 判断日期数组中是否有重复的日期
     *
     * @param periodStart
     * @param periodend
     * @return
     */
    public static boolean isOverlap(List<Timestamp> periodStart, List<Timestamp> periodend) {
        /**
         * 两两循环比较
         */
        for (int i = 0; i < periodStart.size() - 1; i++) {
            Timestamp start0 = periodStart.get(i);
            Timestamp end0 = periodend.get(i);
            for (int j = i + 1; j < periodStart.size(); j++) {
                Timestamp start = periodStart.get(j);
                Timestamp end = periodend.get(j);
                if (start0.compareTo(end) >= 0 || end0.compareTo(start) <= 0) {
                    /**
                     * 说明不重复。
                     * 思路：该时间段的开始时间如何大于另个一个时间段的结束时间，那么这个两个时间段不会有重叠；
                     * 如果该时间段的结束时间小于另一个时间段的时间，那么这个两个时间段也不会有重叠。
                     */
                    continue;
                } else {
                    //说明该时间段重复
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取两个时间中间隔分钟
     *
     * @param beginTime
     * @param endTime
     * @return
     */
    public static Long getIntervalMinutes(String beginTime, String endTime) throws MzException {
        //把当前时间和要比较的时间转换为Date类型，目的在于得到这两个时间的毫秒值
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        Date parse = null;
        Date now = null;
        try {
            parse = sdf.parse(beginTime);
            now = sdf.parse(endTime);
        } catch (ParseException e) {
            log.error("时间转换异常！");
            throw new MzException("日期格式错误");
        }
        //获得这两个时间的毫秒值后进行处理(因为我的需求不需要处理时间大小，所以此处没有处理，可以判断一下哪个大就用哪个作为减数。)
        long diff = now.getTime() - parse.getTime();
        //此处用毫秒值除以分钟再除以毫秒既得两个时间相差的分钟数
        return diff / 60 / 1000;
    }

    /**
     * 判断当前日期是否是周末
     *
     * @param requestDay
     * @return
     */
    public static boolean isWeekend(Date requestDay) {
        if (requestDay == null) {
            return false;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(requestDay);
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }


    public static void main(String[] args) {
        System.out.println(DateUtil.differentDaysByMillisecond(DateUtil.pase("201-04-29","yyyy-MM-dd"),DateUtil.pase("201-05-11","yyyy-MM-dd")));
        System.out.println(DateUtil.getBetweenDatesDesc(DateUtil.pase("201-04-29","yyyy-MM-dd"),DateUtil.pase("201-05-11","yyyy-MM-dd")).size());
        System.out.println(DateUtil.IsAfternoon(java.util.Calendar.getInstance().getTime().getHours()));
    }

    /**
     * 获取年龄
     *
     * @param birthDay
     * @return
     * @throws Exception
     */
    public static int getAge(Date birthDay) {
        Calendar cal = Calendar.getInstance();
        if (cal.before(birthDay)) { //出生日期晚于当前时间，无法计算
//            throw new IllegalArgumentException(
//                    "The birthDay is before Now.It's unbelievable!");
            return 0;
        }
        int yearNow = cal.get(Calendar.YEAR);  //当前年份
        int monthNow = cal.get(Calendar.MONTH);  //当前月份
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期
        cal.setTime(birthDay);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
        int age = yearNow - yearBirth;   //计算整岁数
        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前，年龄减一
            } else {
                age--;//当前月份在生日之前，年龄减一
            }
        }
        return age;
    }


    /**
     *
     * 获取两个日期的间隔天数
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
        return days;
    }

}



