package com.xiaomai.utils;

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

public class TimeUtils {
    static SimpleDateFormat sdf_hms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    static SimpleDateFormat sdf_hm = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd");
    static String DAY_OF_START = " 00:00:00";
    static String DAY_OF_END = " 23:59:59";

    private static Date praseDate(String time, SimpleDateFormat sdf) {
        try {
            return sdf.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @Description: 获取当天某一时分的时间
     * @Author: pdd
     * @Date: 2020/11/26/15:27
     */
    public static long getToDayTime(int hour, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, 0);

        Date d = calendar.getTime();
        String day = sdf_hm.format(d) + ":00";
        Date today_date = praseDate(day, sdf_hms);
        long data = today_date.getTime();
        return data;
    }

    /**
     * @Description: 获取当天某一时分的时间
     * @Author: pdd
     * @Date: 2020/11/26/15:27
     */
    public static long getCurrentTime(int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, 0);

        Date d = calendar.getTime();
        String day = sdf_hm.format(d) + ":00";
        Date today_date = praseDate(day, sdf_hms);
        long data = today_date.getTime();
        return data;
    }


    /**
     * @Description: 获取当天某一时分的时间
     * @Author: pdd
     * @Date: 2020/11/26/15:27
     */
    public static long getDayTime(int addDay, int hour, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, addDay);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, 0);


        Date d = calendar.getTime();
        String day = sdf_hm.format(d) + ":00";
        Date today_date = praseDate(day, sdf_hms);
        long data = today_date.getTime();
        return data;
    }


    /**
     * @return 获取当天日期时间戳（0点）
     */
    public static long getTodayTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());

        Date d = calendar.getTime();
        String day = sdf_day.format(d) + " 00:00:00";
        Date today_date = praseDate(day, sdf_hms);

        return today_date.getTime();
    }

    /**
     * @return 获取当天结束日期时间戳（24点）
     */
    public static long getTodayEndTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);

        long today_end_date = calendar.getTime().getTime();

        return today_end_date;
    }

    /**
     * @return 获取当天结束日期时间戳（24点）
     */
    public static long getTodayEndTime(int addDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, addDay);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);

        long today_end_date = calendar.getTime().getTime();

        return today_end_date;
    }

    /**
     * @return 获取当前时间戳
     */
    public static long getCurrentTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        long today_date = calendar.getTime().getTime();
        return today_date;
    }
    /**
     * @return 当前时间的小时数
     */
    public static int hourOfDay(){
        Calendar calendar = Calendar.getInstance(); // 获取当前时间戳
        int hourOfDay =  calendar.get(Calendar.HOUR_OF_DAY); //24小时制
        return hourOfDay;
    }
    /**
     * @return 今年的1月1日0点
     */
    public static long getStartYear(){
        //获取当前日期
        Calendar calendar = Calendar.getInstance();

        //将当前日期设置为1月1日
        calendar.set(Calendar.MONTH,Calendar.JANUARY);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        //将时间设置为0点
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);

        long getStartYear = calendar.getTimeInMillis();
        return getStartYear;
    }
    /**
     * @return 今年的12月31日23点59分59秒
     */
    public static long getEndYear(){
        //获取当前日期
        Calendar calendar = Calendar.getInstance();
        //清除所有字段
        calendar.clear();
        calendar.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR)); // 设置当前年份
        calendar.set(Calendar.MONTH, Calendar.DECEMBER); // 设置为12月
        calendar.set(Calendar.DATE, 31); // 设置为31号
        calendar.set(Calendar.HOUR_OF_DAY, 23); // 设置为23点
        calendar.set(Calendar.MINUTE, 59); // 设置为59分
        calendar.set(Calendar.SECOND, 59); // 设置为59秒
        calendar.set(Calendar.MILLISECOND,59);

        long getEndYear = calendar.getTimeInMillis();
        return getEndYear;
    }

    /**
     * @return 获取当前时间戳
     */
    public static long getCurrentTime_AddMinute(int addMinute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, addMinute);
        calendar.set(Calendar.SECOND, 0);

        Date d = calendar.getTime();
        String day = sdf_hm.format(d) + ":00";
        Date date = praseDate(day, sdf_hms);
        return date.getTime();
    }

    public static long getCurrentTime_AddMinute1(int addMinute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, addMinute);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        Date d = calendar.getTime();
        String day = sdf_hm.format(d) + ":00:00";
        Date date = praseDate(day, sdf_hms);
        return date.getTime();
    }

    // 获取一周前的日期
    public static long getLastWeekDate() {
        // 获取一周前的时间

        Calendar c_1 = Calendar.getInstance();
        c_1.setTime(new Date());
        c_1.add(Calendar.DATE, -7);
        Date d = c_1.getTime();
        String lastweek_day = sdf_day.format(d) + " 00:00:00";
        Date lastweek_date = null;
        lastweek_date = praseDate(lastweek_day, sdf_hms);

        long lastweek_time = lastweek_date.getTime();


        return lastweek_time;
    }

    // 获取几天后的23：59：59
    public static long getAfterDayDate(int addDay) {
        // 获取几天后的时间
        SimpleDateFormat sdf_hms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c_1 = Calendar.getInstance();
        c_1.setTime(new Date());
        c_1.add(Calendar.DATE, +addDay);
        Date d = c_1.getTime();
        String lastday_day = sdf_day.format(d) + " 23:59:59";
        Date lastday_date = null;
        lastday_date = praseDate(lastday_day, sdf_hms);

        long afterday_time = lastday_date.getTime();
        return afterday_time;
    }

    // 获取几天前的00：00：00
    public static long getBeforeDayDate(int addDay) {
        // 获取几天后的时间
        SimpleDateFormat sdf_hms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c_1 = Calendar.getInstance();
        c_1.setTime(new Date());
        c_1.add(Calendar.DATE, -addDay);
        Date d = c_1.getTime();
        String lastday_day = sdf_day.format(d) + " 00:00:00";
        Date lastday_date = null;
        lastday_date = praseDate(lastday_day, sdf_hms);

        long afterday_time = lastday_date.getTime();
        return afterday_time;
    }

    /**
     * 获取数月后日期时间戳
     *
     * @param sDate    初始时间
     * @param addMonth 增加的月份数
     * @param addDay   增加的天数
     * @return
     * @throws ParseException
     */
    public static long getAfterMonthDate(long sDate, int addMonth, int addDay) {
        SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd");

        Date smdate = new Date(sDate);
        Calendar c_1 = Calendar.getInstance();
        c_1.setTime(smdate);

        //购买一个月的课程
        c_1.add(Calendar.MONTH, +addMonth);
        // 计算时需要减去最后一天时间，不记入时间计算
        c_1.add(Calendar.DATE, -1);
        // 计算赠送的天数
        c_1.add(Calendar.DATE, +addDay);

        Date lastweek_aftermonth_d = c_1.getTime();
        String lastweek_aftermonth = sdf_day.format(lastweek_aftermonth_d) + " 00:00:00";

        Date date_month = praseDate(lastweek_aftermonth, sdf_hms);

        long time_month = date_month.getTime();
        return time_month;

    }


    /**
     * 获取数月前的日期
     *
     * @param sDate    初始时间
     * @param addMonth 往前数的月份数
     * @param addDay   往前增加的天数
     * @return
     * @throws ParseException
     */
    public static long getLastrMonthDate(long sDate, int addMonth, int addDay) {
        SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf_hms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date smdate = new Date(sDate);
        Calendar c_1 = Calendar.getInstance();
        c_1.setTime(smdate);

        //购买一个月的课程
        c_1.add(Calendar.MONTH, -addMonth);
        // 计算赠送的天数
        c_1.add(Calendar.DATE, -addDay);
        // 计算时需要减去最后一天时间，不记入时间计算
        c_1.add(Calendar.DATE, 1);

        Date lastweek_aftermonth_d = c_1.getTime();
        String lastweek_aftermonth = sdf_day.format(lastweek_aftermonth_d) + " 00:00:00";
        Date date_month = praseDate(lastweek_aftermonth, sdf_hms);

        long time_month = date_month.getTime();

        return time_month;

    }

    /**
     * @return 获取当月第一天时间戳   零点零分
     * @throws ParseException
     */
    public static long getMonthFristDay(int... addMonth) {
        Calendar c = Calendar.getInstance();

        if (addMonth.length > 0) {
            c.add(Calendar.MONTH, addMonth[0]);
        }
        c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天

        Date lastweek_aftermonth_d = c.getTime();
        String lastweek_aftermonth = sdf_day.format(lastweek_aftermonth_d) + " 00:00:00";
        Date date_month = praseDate(lastweek_aftermonth, sdf_hms);

        long time_month = date_month.getTime();
        return time_month;
    }

    /**
     * @return 获取当月第最后一天时间戳   零点零分
     * @throws ParseException
     */
    public static long getMonthLastDay(int... addMonth) {
        //获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        if (addMonth.length > 0) {
            ca.add(Calendar.MONTH, addMonth[0]);
        }

        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date lastweek_aftermonth_d = ca.getTime();
        String lastweek_aftermonth = sdf_day.format(lastweek_aftermonth_d) + " 00:00:00";
        Date date_month = praseDate(lastweek_aftermonth, sdf_hms);
        long time_month = date_month.getTime();
        return time_month;

    }

    /**
     * @return 获取当月最后一天时间戳   23：59：59
     * @throws ParseException
     */
    public static long getMonthLastTime(int... addMonth) {
        //获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        if (addMonth.length > 0) {
            ca.add(Calendar.MONTH, addMonth[0]);
        }
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date lastweek_aftermonth_d = ca.getTime();
        String lastweek_aftermonth = sdf_day.format(lastweek_aftermonth_d) + " 23:59:59";
        Date date_month = praseDate(lastweek_aftermonth, sdf_hms);
        long time_month = date_month.getTime();
        return time_month;

    }

    /**
     * @param addWeek 需增加的周数(eg : 为1 表示 下周周一, -1 表示上周周一)
     * @Description:获取当周第一天时间戳 零点零分
     * @Author: pdd
     * @Date: 2021/6/19/17:42
     */
    public static String getWeekFirstTime(int... addWeek) {
        Calendar cld = Calendar.getInstance(Locale.CHINA);
        cld.setFirstDayOfWeek(Calendar.MONDAY);//以周一为首日

        if (addWeek.length > 0) {
            cld.add(Calendar.DATE, addWeek[0] * 7);
        }
        cld.set(Calendar.HOUR_OF_DAY, 0);
        cld.set(Calendar.MINUTE, 0);
        cld.set(Calendar.SECOND, 0);
        cld.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);//周一

        String date_str = sdf_day.format(cld.getTime()) + " 00:00:00";
        Date date = praseDate(date_str, sdf_hms);
        return String.valueOf(date.getTime());
    }

    /**
     * @return 获取当周最后一天时间戳   23：59：59
     * @throws ParseException
     */
    public static String getWeekLastTime(int... weeksNum) {
        Calendar cld = Calendar.getInstance(Locale.CHINA);
        int week = cld.get(Calendar.DAY_OF_WEEK);
        cld.add(Calendar.DATE, 8 - week);

        if (weeksNum.length > 0) {
            cld.add(Calendar.DATE, weeksNum[0] * 7);
        }

        cld.set(Calendar.HOUR_OF_DAY, 23);
        cld.set(Calendar.MINUTE, 59);
        cld.set(Calendar.SECOND, 59);
        // String endWeekTime = String.valueOf(cld.getTime().getTime());

        String endWeekTime = sdf_day.format(cld.getTime()) + " 23:59:59";
        Date date = praseDate(endWeekTime, sdf_hms);
        return String.valueOf(date.getTime());
    }

    /**
     * 获取两个日期之间的天数差
     *
     * @param time_s 起始时间
     * @param time_e 结束时间
     * @return
     * @throws ParseException
     */
    public static int daysBetween(long time_s, long time_e) {


        long between_days = (time_e - time_s) / (1000 * 3600 * 24);

        // 消耗天数，需计算当天
        int daysBetween = Integer.parseInt(String.valueOf(between_days)) + 1;

        return Integer.parseInt(String.valueOf(daysBetween));
    }


    /**
     * 获取当前日期 ”yyyymmdd“
     *
     * @return
     */
    public static String getCurrentDateString() {
        SimpleDateFormat sdf_day = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        String today_date = sdf_day.format(calendar.getTime());
        return today_date;
    }

    /**
     * @description:获取某一天yyyymmdd
     * @param day
     * @return: java.lang.String
     **/
    public static String getCurrentDateString(int day) {
        SimpleDateFormat sdf_day = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH,day);
        String date = sdf_day.format(calendar.getTime());
        return date;
    }
    /**
     * 获取当前日期 ”yyyymmddHHmm“
     *
     * @return
     */
    public static String getCurrentDateString1() {
        SimpleDateFormat sdf_day = new SimpleDateFormat("yyyyMMddHHmm");
        Calendar calendar = Calendar.getInstance();
        String today_date = sdf_day.format(calendar.getTime());
        return today_date;
    }

    /**
     * 获取当前日期 ”yyyymmdd“
     *
     * @return
     */
    public static String getCurrentTimeString() {
        SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Calendar calendar = Calendar.getInstance();
        String today_date = sdf_day.format(calendar.getTime());
        return today_date;
    }

    public static void main(String[] args) {
        System.out.println(Math.floorDiv(1, 3));
        System.out.println(Math.floorDiv(12, 3));
        System.out.println(Math.floorDiv(11, 3));
    }

    /**
     * @Description: 获取本年度某一个季度的 开始和结束时间
     * @Author: pdd
     * @Date: 2021/6/22/16:42
     */
    public static Map<String, Long> getCurrentYearQuarterStartEndTime(int... quarter) {
        return getQuarterStartEndTime(0, quarter);
    }

    public static Map<String, Long> getQuarterStartEndTime(int addYear, int... quarter) {
        Map<String, Long> result = new HashMap<>();
        Calendar start = Calendar.getInstance();
        start.add(Calendar.YEAR, addYear);
        Calendar end = Calendar.getInstance();
        end.add(Calendar.YEAR, addYear);

        int month = start.get(Calendar.MONTH) + 1;
        int quarterNum = quarter.length > 0 ? quarter[0] : getQuarterOfMonth(month);

        if (quarterNum == 1) {
            start.set(Calendar.MONTH, 0);
            end.set(Calendar.MONTH, 2);
        } else if (quarterNum == 2) {
            start.set(Calendar.MONTH, 3);
            end.set(Calendar.MONTH, 5);
        } else if (quarterNum == 3) {
            start.set(Calendar.MONTH, 6);
            end.set(Calendar.MONTH, 8);
        } else if (quarterNum == 4) {
            start.set(Calendar.MONTH, 9);
            end.set(Calendar.MONTH, 11);
        }

        start.set(Calendar.DAY_OF_MONTH, 1);
        result.put("startTime", praseDateTime(start, DAY_OF_START));


        end.set(Calendar.DAY_OF_MONTH, end.getActualMaximum(Calendar.DAY_OF_MONTH));
        result.put("endTime", praseDateTime(end, DAY_OF_END));

        return result;

    }

    private static Long praseDateTime(Calendar ca, String hms) {
        Date date = ca.getTime();

        String dateStr = sdf_day.format(date) + hms;
        date = praseDate(dateStr, sdf_hms);
        return date.getTime();

    }

    public static int getQuarterOfMonth(int month) {
        if (1 <= month && month <= 3) {
            return 1;
        } else if (4 <= month && month <= 6) {
            return 2;
        } else if (7 <= month && month <= 9) {
            return 3;
        } else if (10 <= month && month <= 12) {
            return 4;
        } else {
            return 1;
        }
    }

}
