package com.miyzh.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

public class DateUtils {

    public static final String FORMAT_YYYY_MM_DD = "yyyy-MM-dd";
    public static final String FORMAT_HHMM = "HH:mm";
    public static final String FORMAT_YYYYMMDDHHMM = "yyyy-MM-dd HH:mm";
    public static final String FORMAT_YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_YYYYMMDD = "yyyyMMdd";
    public static final String FORMAT_YYMMDD = "yyMMdd";
    public static final String FORMAT_YYYY_MM = "yyyy-MM";
    public static final String FORMAT_YYYY = "yyyy";
    public static final String MAX_DATE = "9999-12-31";
    private static final long yearSecond = 365 * 24 * 60 * 60 * 1000L;
    private static final long monthSecond = 30 * 24 * 60 * 60 * 1000L;

    /**
     * 时间格式 2016-08-15T16:00:00.000Z
     * 想要展示的时间格式是yyyy-MM-DD HH:mm:ss
     * @param UTCString
     * @return
     */
    public static String UTCStringtODefaultString(String UTCString) {
        try {

            UTCString = UTCString.replace("Z", " UTC");
            SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
            SimpleDateFormat defaultFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = utcFormat.parse(UTCString);
            return defaultFormat.format(date);


        } catch (ParseException pe) {
            pe.printStackTrace();
            return UTCString;
        }
    }

    /**
     * 通过生日获取岁数-年
     *
     * @param birthday
     * @return
     */
    public static int getYearByBirthday(String birthday) {
        if (StringUtils.isBlank(birthday)) {
            return 0;
        }
        int year = Integer.parseInt(birthday.split("-")[0]);
        int month = Integer.parseInt(birthday.split("-")[1]);
        Calendar calendar = Calendar.getInstance();
        int yearNow = calendar.get(Calendar.YEAR);
        int monthNow = calendar.get(Calendar.MONTH) + 1;
        if (monthNow < month) {
            return yearNow - year - 1;
        }
        return yearNow - year;
        // int thisAge = 0;
        // Date today = new Date();
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // Date birthDate = null;
        // try {
        // birthDate = sdf.parse(birthday);
        // } catch (ParseException e) {
        // e.printStackTrace();
        // return 0;
        // }
        // thisAge = today.getYear() - birthDate.getYear();
        // if (today.getMonth() < birthDate.getMonth()) {// 月份超过
        // thisAge -= 1;
        // } else if (today.getMonth() == birthDate.getMonth()) {
        // if (today.getDate() < birthDate.getDate()) {
        // thisAge -= 1;
        // }
        // }
        // return thisAge;
    }

    /**
     * 通过生日获取岁数-月
     *
     * @param birthday
     * @return
     */
    public static int getMonthByBirthday(String birthday) {
        if (StringUtils.isBlank(birthday)) {
            return 0;
        }
        int month = Integer.parseInt(birthday.split("-")[1]);
        Calendar calendar = Calendar.getInstance();
        int monthNow = calendar.get(Calendar.MONTH) + 1;
        if (monthNow < month) {
            return monthNow + 12 - month;
        }
        return monthNow - month;
        // int thisMonth = 0;
        // Date today = new Date();
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // Date birthDate = null;
        // try {
        // birthDate = sdf.parse(birthday);
        // } catch (ParseException e) {
        // e.printStackTrace();
        // return 0;
        // }
        // if (today.getMonth() > birthDate.getMonth()) {// 月份超过
        // thisMonth = today.getMonth() - birthDate.getMonth();
        // } else if (today.getMonth() == birthDate.getMonth()) {// 按天数计算生日
        // if (today.getDate() > birthDate.getDate()) {
        // thisMonth = 1;
        // } else if (today.getDate() < birthDate.getDate()) {
        // thisMonth = 11;
        // }
        // } else {
        // thisMonth = today.getMonth() - birthDate.getMonth() + 12;
        // }
        // return thisMonth;
    }

    /**
     * 获取指定格式时间字符串
     *
     * @param pattern 自定义格式 yyyy-MM-dd HH:mm:ss
     * @param date    Date类型日期
     * @return String 字符串格式日期
     */
    public static String getStrDateFormat(String pattern, Date date) {
        if (date == null) {
            date = new Date();
        }
        SimpleDateFormat fmt = new SimpleDateFormat();
        fmt.applyPattern(pattern);
        String dateStr = fmt.format(date);
        return dateStr;
    }

    /**
     * 根据年月粗略计算生日
     *
     * @param age
     * @param monthInt
     * @return
     */
    public static String getBirthday(int age, int monthInt) {
        Calendar calendar = Calendar.getInstance();
        int thisYear = calendar.get(Calendar.YEAR);
        int thisMonth = calendar.get(Calendar.MONTH);
        String realDay = "01";

        if (0 == age && 0 == monthInt) {
            return thisYear + "-" + (thisMonth + 1) + "-" + realDay;
        }
        int year = thisYear;
        String month = monthInt + 1 + "";
        if (monthInt <= thisMonth) {
            year = thisYear - age;
            month = thisMonth - monthInt + 1 + "";
        } else if (monthInt > thisMonth) {
            year = thisYear - age - 1;
            month = 12 - monthInt + thisMonth + 1 + "";
        }
        if (month.length() < 2) {
            month = "0" + month;
        }
        return year + "-" + month + "-" + realDay;
    }

    /**
     * 获取指定格式的日期
     *
     * @param format
     * @return
     */
    public static String getCurrent(String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        return simpleDateFormat.format(new Date());
    }

    /**
     * 获取给定时间date的前day天
     *
     * @param date
     * @param day
     * @return
     */
    public static Date getDateBeforeDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -day);
        Date _date = calendar.getTime();
        return _date;
    }



    /**
     * 获取给定时间后day天
     *
     * @param date
     * @param day
     * @return Date each engineer has a duty to keep the code elegant
     * @author: qin.jian 2014-2-13 下午2:15:17
     */
    public static Date getDateAfterDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        Date _date = calendar.getTime();
        return _date;
    }

    /**
     * 获取指定格式时间字符串
     *
     * @param pattern 自定义格式 yyyy-MM-dd HH:mm:ss
     * @param dateStr String 日期格式字符
     * @return Date类型日期 each engineer has a duty to keep the code elegant
     * @throws ParseException
     * @author: slzs 2013-12-18 下午3:30:06
     */
    public static Date getDateFormat(String pattern, String dateStr) throws ParseException {
        SimpleDateFormat fmt = new SimpleDateFormat();
        if (pattern == null && dateStr != null) {
            if (dateStr.length() == 19) {
                fmt.applyPattern("yyyy-MM-dd HH:mm:ss");
            } else if (dateStr.length() == 16) {
                fmt.applyPattern("yyyy-MM-dd HH:mm");
            } else if (dateStr.length() == 13) {
                fmt.applyPattern("yyyy-MM-dd HH");
            } else {
                fmt.applyPattern("yyyy-MM-dd");
            }
        } else {
            fmt.applyPattern(pattern);
        }
        Date date = fmt.parse(dateStr);
        return date;
    }

    /**
     * 指定日期获取星期几
     *
     * @param date
     * @return
     * @author: liujie
     */
    public static int getWeekByDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int day_of_week = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) day_of_week = 7;
        return day_of_week;
    }

    /**
     * 指定日期及星期几，返回日期
     *
     * @param date
     * @param week
     * @return
     * @author: liujie
     */
    public static String getStrDateByWeek(String pattern, Date date, int week) {
        SimpleDateFormat fmt = new SimpleDateFormat();
        if (StringUtils.isNotBlank(pattern)) {
            fmt.applyPattern(pattern);
        } else {
            fmt.applyPattern("yyyy-MM-dd");
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        int day_of_week = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) day_of_week = 7;

        cal.add(Calendar.DATE, -day_of_week + week);

        return fmt.format(cal.getTime());
    }

    /**
     * 获取时间范围
     *
     * @param date
     * @return 0 上午（0点-12点之前） 1下午（12点-18点） 2 晚上（18点-24点）
     */
    public static int getTimeRange(Date date) {
        if (date == null) {
            return -1;
        }
        String time = DateFormatUtils.format(date, "HH:mm:ss");
        if (time.compareTo("00:00:00") >= 0 && time.compareTo("12:00:00") < 0) {
            return 0;
        } else if (time.compareTo("12:00:00") >= 0 && time.compareTo("18:00:00") < 0) {
            return 1;
        } else {
            return 2;
        }
    }

    /**
     * 获取时间范围名称
     *
     * @param timeRange
     * @return
     */
    public static String getTimeRangeStr(int timeRange) {
        switch (timeRange) {
            case 0:
                return "上午";
            case 1:
                return "下午";
            case 2:
                return "晚上";
            default:
                return "";
        }
    }

    /**
     * 根据日期获取时间范围
     *
     * @param date
     * @return
     */
    public static String getTimeRangeStr(Date date) {
        return getTimeRangeStr(getTimeRange(date));
    }

    /**
     * 获取周名称
     *
     * @param week
     * @return
     */
    public static String getWeekStr(int week) {
        switch (week) {
            case 1:
                return "星期一";
            case 2:
                return "星期二";
            case 3:
                return "星期三";
            case 4:
                return "星期四";
            case 5:
                return "星期五";
            case 6:
                return "星期六";
            case 7:
                return "星期日";
        }
        return "未知";
    }

    public static String getWeekStr(String dateStr) {
        String week = null;
        try {
            Date date = getDateFormat(FORMAT_YYYY_MM_DD, dateStr);
            week = getWeekStr(getWeekByDate(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return week;
    }

    /**
     * 计算时间差
     *
     * @param startDate
     * @param endDate
     * @param timeUnit  支持 秒，分钟，小时，天
     * @return
     */
    public static long dateDiff(Date startDate, Date endDate, TimeUnit timeUnit) {
        if (startDate == null) {
            startDate = new Date();
        }
        if (endDate == null) {
            endDate = new Date();
        }

        long diff = (endDate.getTime() - startDate.getTime()) / 1000; // 秒
        switch (timeUnit) {
            case MINUTES:
                diff = diff / 60;
                break;
            case HOURS:
                diff = diff / (60 * 60);
                break;
            case DAYS:
                diff = diff / (60 * 60 * 24);
                break;
            case SECONDS:
            default:
        }
        return diff;
    }

    /**
     * 内部方法。为指定日期增加相应的天数或月数
     *
     * @param date   基准日期
     * @param amount 增加的数量
     * @param field  增加的单位，年，月或者日
     * @return 增加以后的日期
     */
    public static Date add(Date date, int amount, int field) {
        Calendar calendar = Calendar.getInstance();

        calendar.setTime(date);
        calendar.add(field, amount);

        return calendar.getTime();
    }

    /**
     * 得到系统当前日期时间
     *
     * @return 当前日期时间
     */
    public static Date getNow() {
        return Calendar.getInstance().getTime();
    }

    public static Date addDays(int days) {
        return add(getNow(), days, Calendar.DATE);
    }

    /**
     * 取得指定日期以后若干天的日期。如果要得到以前的日期，参数用负数。
     *
     * @param date 基准日期
     * @param days 增加的日期数
     * @return 增加以后的日期
     */
    public static Date addDays(Date date, int days) {
        return add(date, days, Calendar.DATE);
    }


    /**
     * 初始化购买效期
     *
     * @param date
     * @param month
     * @return
     */
    public static Date initLicenseDay(Date date, int month) {
        Date after = add(date, month, Calendar.MONTH);
        return after;
    }

    public static Date getBeginTime(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate localDate = yearMonth.atDay(1);
        LocalDateTime startOfDay = localDate.atStartOfDay();
        ZonedDateTime zonedDateTime = startOfDay.atZone(ZoneId.of("Asia/Shanghai"));

        return Date.from(zonedDateTime.toInstant());
    }

    public static Date getEndTime(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate endOfMonth = yearMonth.atEndOfMonth();
        LocalDateTime localDateTime = endOfMonth.atTime(23, 59, 59, 999);
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
        return Date.from(zonedDateTime.toInstant());
    }

    /**
     * date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2)   //同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)    //闰年
                {
                    timeDistance += 366;
                } else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else    //不同年
        {
//            System.out.println("判断day2 - day1 : " + (day2-day1));
            return day2 - day1;
        }
    }

    //获取指定日期月份的最后一天
    public static String getLastDayOfMonth(Date date) {
        int year = date.getYear() + 1900;
        int month = date.getMonth() + 1;
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
        return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
    }

    //获取指定日期月份的第一天
    public static String getFirstDayOfMonth(Date date) {
        int year = date.getYear() + 1900;
        int month = date.getMonth() + 1;
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));
        return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
    }

    //获取时间段内有几个月
    public static int getHowMuchMonths(String str1, String str2) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar bef = Calendar.getInstance();
        Calendar aft = Calendar.getInstance();
        bef.setTime(sdf.parse(str1));
        aft.setTime(sdf.parse(str2));
        int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
        int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;

        return Math.abs(month + result) + 1;
    }

//    中国标准时间格式化
    public static String timeKit(String strDate){
        SimpleDateFormat normalFormatter = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat cstFormatter= new SimpleDateFormat("EEE MMM dd yyyy hh", Locale.ENGLISH);
        try {
            if(strDate!=null){
                Date cstDate = cstFormatter.parse(strDate);
                strDate= normalFormatter.format(cstDate);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return strDate;
    }


    public static void main(String[] args) throws Exception {
//        Date dateBeforeDay = DateUtils.getDateBeforeDay(new Date(), 1);
//        System.out.println(dateBeforeDay);
//        String birthday = getBirthday(0, 0);
//        System.out.println(birthday);
//        System.out.println(DateUtils.getStrDateFormat(DateUtils.FORMAT_YYYY_MM_DD,DateUtils.getBeginTime(2016,2)));
//        System.out.println(DateUtils.getStrDateFormat(DateUtils.FORMAT_YYYY_MM_DD,DateUtils.getEndTime(2016,2)));
        // System.out.println(getYearByBirthday(birthday) + "岁" + getMonthByBirthday(birthday) +
        // "月");
        // System.out.println(getStrDateFormat("yyyy-MM-dd", getDateAfterDay(new Date(), 7)));
        System.out.println(DateUtils.timeKit("Sun Mar 01 2020 14:25:52 GMT 0800 (中国标准时间)"));
    }
}
