package com.dst.slms.util;

import com.dst.slms.common.utils.UIRuleUtil;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期格式化工具类
 * 2019-06-28
 * yc
 */
public class DateUtil {
    public static final String DATE_YEAR = "yyyy";
    public static final String DATE_SHORTS = "yyyyMMdd";
    public static final String DATE_SHORT = "yyyy-MM-dd";
    public static final String YEAR_MONTH = "yyyy-MM";
    public static final String DATE_LANG = "yyyy-MM-dd HH:mm:ss";
    public static final SimpleDateFormat SDF_SHORTS = new SimpleDateFormat("yyyyMMdd");
    public static final SimpleDateFormat SDF_SHORT = new SimpleDateFormat("yyyy-MM-dd");
    public static final SimpleDateFormat SDF_LONG = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static final SimpleDateFormat SDF_TIME = new SimpleDateFormat("HH:mm:ss");
    public static final String [] monthArr = {"一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"};
    
    
	/**
	 * @description  计算两个之间的小时数
	 * @param  starAmp  结束时间     时间格式HH:mm:ss
	 * @param  endAmp  结束时间    时间格式HH:mm:ss
	 * @date  2019/10/18 16:19
	 * @author  wanghb
	 * @edit 
	 */
    public static BigDecimal getHourCount(String starAmp,String endAmp){
    	if("".equals(starAmp) || "".equals(endAmp)){
    		return BigDecimal.ZERO;
    	}
		String nowDate = toString(new Date(), DATE_SHORT);
		starAmp = nowDate + " " + starAmp;
		endAmp = nowDate + " " + endAmp;
        long diff = 0;
        try {
            diff = toDate(endAmp, DATE_LANG).getTime() - toDate(starAmp, DATE_LANG).getTime();
        } catch (Exception e) {
            return BigDecimal.ZERO;
        }
		long hour = (diff / (60 * 60 * 1000));
		return UIRuleUtil.getBigDecimal(hour);
	}
    
	/**
	 * @description  两个时间的大小比较
	 * @param  time1  结束时间     时间格式HH:mm:ss
	 * @param  time2  结束时间    时间格式HH:mm:ss
	 * @date  2019/10/18 16:19
	 * @author  wanghb
	 * @edit 
	 */
    public static Boolean hourDiff(String time1,String time2){
    	if("".equals(time1) || "".equals(time2)){
    		return false;
    	}
		String nowDate = toString(new Date(), DATE_SHORT);
		time1 = nowDate + " " + time1;
		time2 = nowDate + " " + time2;
		return toDate(time1, DATE_LANG).getTime() >= toDate(time2, DATE_LANG).getTime();
	}

    /**
     * @description  .
     * @param  time  时间格式HH:mm:ss
     * @param  calendarType  类型  例: Calendar.MINUTE 分钟
     * @param  Quantity  数量加多少
     * return  .
     * @date  20/04/27 10:36
     * @author  wanghb
     * @edit  .
     */
    public static String timeCount(String time,int calendarType,Integer Quantity){
        String nowDate = toString(new Date(), DATE_SHORT);
        time = nowDate + " " + time;
        Date date = toDate(time, DATE_LANG);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendarType, Quantity);
        String returnTime = toString( calendar.getTime(),DATE_LANG ).substring( 11,19 );
        return returnTime;

    }


    /**
     * 获取当年年分
     * @param
     * @return
     */
    public static String getCurrentDate() {
        return toString(new Date(), DATE_YEAR);
    }

    /**
     * 获取某个月份的的第一天
     * @return index 0 为当前学  1为下个月  -1为上个月  以此类推
     * @author wanghb
     * @date 2019-06-25
     */
    public static Date getMonthFirstDay(Integer index){
        if(index == null){
            return null;
        }
        Calendar cale = Calendar.getInstance();
        cale.add(Calendar.MONTH, index);
        cale.set(Calendar.DAY_OF_MONTH, 1);
        return cale.getTime();//当前月的第一天
    }
    public static final String[] weeksI = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
    public static final String[] weeksII = {"日","一","二","三","四","五","六"};
    /**
     * 通过日期获取星期
     * @return String  date
     * @author wanghb
     * @date 2019-06-25
     */
    public static String getWeek(Date date ,String[] weeks){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if(week_index<0){
            week_index = 0;
        }
        return UIRuleUtil.getString(weeks[week_index]);
    }

    /**
     * 获取中间日期
     * @return start 开始日期
     * @return end 结束日期
     * @author wanghb
     */
    public static List<String> getMiddleDate(Date start, Date end) {
        List<String> list = new ArrayList<>();
        long s = start.getTime();
        long e = end.getTime();
        Long oneDay = 1000 * 60 * 60 * 24l;
        while (s <= e) {
            start = new Date(s);
            list.add(new SimpleDateFormat("yyyy-MM-dd").format(start));
            s += oneDay;
        }
        return list;
    }


    /**
     * 日期计算 单位天
     * @return date 要计算的日期
     * @return end 结束日期
     * @author wanghb
     */
    public static Date dateCount(Date date, Integer days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);//当前时间减去一年，即一年前的时间
        return calendar.getTime();
    }

    /**
     * 日期计算 单位天
     * @return date 要计算的日期
     * @return end 结束日期
     * @return calendarType Calendar类的常量   Calendar.YEAR 年  Calendar.DATE 天 Calendar.MONTH 月
     * @author wanghb
     */
    public static Date dateCount(Date date, Integer days,int calendarType) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        //当前时间减去一年，即一年前的时间
        calendar.add(calendarType, days);
        return calendar.getTime();
    }

    /**
     * 计算两个日期之间的天数
     * @return date 要计算的开始日期
     * @return end 结束日期
     * @author wanghb
     */
    public static long daysCount(Date startDate, Date endDate) {
        if("".equals(UIRuleUtil.getString(startDate)) || "".equals(UIRuleUtil.getString(startDate))){
            return 0;
        }
        //转为毫秒
        long startTime = startDate.getTime();
        long endTime = endDate.getTime();
        long daysConut = endTime - startTime;
        //转为天
        long i = (daysConut/1000/60/60/24);
        return i;
    }

    /**
     * 将Date日期转换为String
     *
     * @param date
     * @param formatStr
     * @return
     */
    public static String toString(Date date, String formatStr) {
        if (null == date || null == formatStr) {
            return "";
        }
        SimpleDateFormat df = new SimpleDateFormat(formatStr);
        return df.format(date);
    }

    /**
     * long 日期转 String
     *
     * @param date
     * @param format
     * @return
     */
    public static String longToDate(long date, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        return df.format(date);
    }

    /**
     * 判断一个时间是上午还是下午
     * 0：上午
     * 1：下午
     * -1 无法识别
     * 格式一定是24小时制
     ** @param format
     * @return
     */
    public static int getAMPM(long aLong, String format) {
        try {
            //Long aLong = Long.valueOf(str);
            String s = DateUtil.longToDate(aLong, "yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = sdf.parse(s);
            GregorianCalendar ca = new GregorianCalendar();
            ca.setTime(date);
            return ca.get(GregorianCalendar.AM_PM);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return -1;
    }


    /**
     * @description 获取两个时间之间的天数
     * @param  startDate  开始时间
     * @param  endDate  结束时间
     * return  .
     * @date  20/04/18 22:31
     * @author  wanghb
     * @edit  .
     */
    public static int daysBetween(Date startDate,Date endDate) {
        try {
            startDate = SDF_SHORT.parse(SDF_SHORT.format(startDate));
            endDate = SDF_SHORT.parse(SDF_SHORT.format(endDate));
            Calendar cal = Calendar.getInstance();
            cal.setTime(startDate);
            long time1 = cal.getTimeInMillis();
            cal.setTime(endDate);
            long time2 = cal.getTimeInMillis();
            long between_days = (time2 - time1) / (1000 * 3600 * 24);
            return Integer.parseInt(String.valueOf(between_days));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return -1;
    }


    /**
     * @description  计算两个时间相差的分钟数
     * @param  endTime  结束时间
     * @param  startTime  开始时间
     * return  bigDecimal2  分钟数
     * @date  2019/11/22 16:30
     * @author
     * @edit  wanghb  代码整理
     */
    public static BigDecimal getdifferenceTime(String endTime, String startTime){
        SimpleDateFormat sd = new SimpleDateFormat("HH:mm:ss");
        // 一天的毫秒数
        long nd = 1000 * 24 * 60 * 60;
        // 一小时的毫秒数
        long nh = 1000 * 60 * 60;
        // 一分钟的毫秒数
        long nm = 1000 * 60;
        // 一秒钟的毫秒数
        long ns = 1000;
        long diff;
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        // 获得两个时间的毫秒时间差异
        try {
            diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
            // 计算差多少天
            day = diff / nd;
            // 计算差多少小时
            hour = diff % nd / nh + day * 24;
            // 计算差多少分钟
            min = diff % nd % nh / nm + day * 24 * 60;
            // 计算差多少秒
            sec = diff % nd % nh % nm / ns;
            long s = (hour - day * 24)*60*60;
            long s1 = (min - day * 24 * 60)*60 + s+sec;
            BigDecimal bigDecimal2 = new BigDecimal(s1);
            bigDecimal2=bigDecimal2.divide(new BigDecimal(60),2,BigDecimal.ROUND_HALF_UP);
            return bigDecimal2;
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return BigDecimal.ZERO;
    }
    
    /**
     * @description  判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     * @param  nowTime  当前时间
     * @param  startTime  开始时间
     * @param  endTime  结束时间
     * @date  2019/10/21 11:32
     * @author  jqlin
     * @edit
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * String 转 date
     * @param str
     * @param format
     * @return
     */
    public static Date toDate(String str,String format){
        if("".equals(UIRuleUtil.getString(str))){
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            return dateFormat.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 本月第一天
     * @return
     */
    public static String getOneDay(int index){

        Calendar cale = Calendar.getInstance();

        cale.add(Calendar.MONTH, 0);

        cale.set(Calendar.DAY_OF_MONTH, index);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        return format.format(cale.getTime());
    }

    /**
     * 获取往前多少天的日期
     * @return
     */
    public static String getFirstday(int index){
        Calendar cale = Calendar.getInstance();

        //获取昨天的日期
        cale = Calendar.getInstance();

        cale.add(Calendar.DATE,1);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        return format.format(cale.getTime());
    }

    /**
     * 获取往前多少天的日期
     * @return
     */
    public static String getYestoday(int index){
        //获取昨天的日期
        Calendar cale = Calendar.getInstance();

        cale.add(Calendar.DATE,index);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        return format.format(cale.getTime());
    }


    public static List<Date> findDates(Date dBegin, Date dEnd)  
    {  
     List lDate = new ArrayList();  
     lDate.add(dBegin);  
     Calendar calBegin = Calendar.getInstance();  
     // 使用给定的 Date 设置此 Calendar 的时间  
     calBegin.setTime(dBegin);  
     Calendar calEnd = Calendar.getInstance();  
     // 使用给定的 Date 设置此 Calendar 的时间  
     calEnd.setTime(dEnd);  
     // 测试此日期是否在指定日期之后  
     while (dEnd.after(calBegin.getTime()))  
     {  
      // 根据日历的规则，为给定的日历字段添加或减去指定的时间量  
      calBegin.add(Calendar.DAY_OF_MONTH, 1);  
      lDate.add(calBegin.getTime());  
     }  
     return lDate;  
    }

    /**
     * 计算2个日期之间相差的  以年、月、日为单位，各自计算结果是多少
     * 比如：2011-02-02 到  2017-03-02
     *                                以年为单位相差为：6年
     *                                以月为单位相差为：73个月
     *                                以日为单位相差为：2220天
     * @param fromDate
     * @param toDate
     * @return
     */
    public static int dayCompare(Date fromDate,Date toDate,String type){
        Calendar  from  =  Calendar.getInstance();
        from.setTime(fromDate);
        Calendar  to  =  Calendar.getInstance();
        to.setTime(toDate);
        int fromYear = from.get(Calendar.YEAR);
        int fromMonth = from.get(Calendar.MONTH);
        int toYear = to.get(Calendar.YEAR);
        int toMonth = to.get(Calendar.MONTH);
        int year = toYear  -  fromYear;
        int month = toYear *  12  + toMonth  -  (fromYear  *  12  +  fromMonth);
        int day = (int) ((to.getTimeInMillis()  -  from.getTimeInMillis())  /  (24  *  3600  *  1000));
        //System.out.println("年："+year+"..."+"月："+month+"..."+"天："+day);
        if("year".equals(type))return day;
        if("month".equals(type))return month;
        if("day".equals(type))return day;
        return  0;
    }

    /**
     * 上一个月的今天
     * @param date
     * @param format1
     * @return
     */
    public static String  getLastMonth(Date date,String format1){
    	SimpleDateFormat fmat = new SimpleDateFormat("yyyy-MM-dd");
    	  Calendar c = Calendar.getInstance();
    	  c.setTime(date);
    	  c.add(Calendar.MONTH, -1);
    	  Date m = c.getTime();
    	  return fmat.format(m);
    }
    //获取系统的当前年份
    public static String getSysYear() {

        Calendar date = Calendar.getInstance();

        String year = String.valueOf(date.get(Calendar.YEAR));

        return year;
    }
    //获取系统的当前年份
    public static String getMonth() {

        Calendar date = Calendar.getInstance();

        String month = String.valueOf(date.get(Calendar.MONTH)+1);

        return month;
    }

    /**
     * 某年某月有多少天
     * @param
     * @return
     */
    public static int getDays(Date date){
       	Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());//设置时间
        int year = cal.get(Calendar.YEAR);//获取年份
        int month=cal.get(Calendar.MONTH);//获取月份
    	cal.set(Calendar.YEAR,year);
    	cal.set(Calendar.MONTH, month - 1);//Java月份才0开始算
    	return cal.getActualMaximum(Calendar.DATE);
    }
    
    /**
     * 获取某一年一共多少天
     * @return
     */
    public static int getcoutDays(int year){
    	Calendar cal = Calendar.getInstance();
    	cal.set(Calendar.YEAR, year);
    	int actualMaximum = cal.getActualMaximum(Calendar.DAY_OF_YEAR);
    	return actualMaximum;
    }

    /**
     * 获取某年最后一天日期
     * @return
     */
    public static Date getCurrYearLast(){
    	Calendar currCal=Calendar.getInstance();
    	int currentYear = currCal.get(Calendar.YEAR);
    	return getYearLast(currentYear);
    	}



    public static Date getYearLast(int year){
    	Calendar calendar = Calendar.getInstance();
    	calendar.clear();
    	calendar.set(Calendar.YEAR, year);
    	calendar.roll(Calendar.DAY_OF_YEAR, -1);
    	Date currYearLast = calendar.getTime();
    	return currYearLast;
    	}

    /**
     * 获取两个日期间的日期集合
     * @param bigtime
     * @param endtime
     * @return
     */
        public static List<Date> getDayList(Date bigtime,Date endtime){
            //定义一个接受时间的集合
            List<Date> lDate = new ArrayList<Date>();
            lDate.add(bigtime);
            Calendar calBegin = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calBegin.setTime(bigtime);
            Calendar calEnd = Calendar.getInstance();
            // 使用给定的 Date 设置此 Calendar 的时间
            calEnd.setTime(endtime);
            // 测试此日期是否在指定日期之后
            while (endtime.after(calBegin.getTime()))  {
                // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
                calBegin.add(Calendar.DAY_OF_MONTH, 1);
                lDate.add(calBegin.getTime());
            }
            return lDate;
        }
}
