package xiaoqu.home.open.utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.converter.Converter;

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

/**
 * @ file_name DateConverter.java
 * @ date 2014-4-9下午5:41:48
 * @ description
 * @ reviewed_by
 */
public class DateToConverter implements Converter<String, Date> {
    protected transient final Log log = LogFactory.getLog(DateToConverter.class);

    public Date convert(String text) {
        log.debug(text);
        if (text == null || "".equals(text)) {
            return null;
        }
        Date date = tryConvert(text, "yyyy-MM-dd");
        if (date != null) {
            return new Date(date.getTime());
        }
        return null;

    }
	public static String getDateAddOrSubyyyyMMdd(int field, int value, Date datetime) {
		String date = "";
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(datetime);
		gc.add(field, value);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		date = df.format(gc.getTime());
		return date;
	}


    public static String formatDateByPattern(Date date,String dateFormat){
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        String formatTimeStr = null;
        if (date != null ) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }




    public static String getCron(Date  date){
        String dateFormat="ss mm HH dd MM ? yyyy";
        return formatDateByPattern(date, dateFormat);
    }

    public Date tryConvert(String text, String pattern) {
        SimpleDateFormat formatDate = new SimpleDateFormat(pattern);
        //dateFormat.setLenient(false);
        try {
            Date date = new Date(formatDate.parse(text).getTime());
            return date;
        } catch (ParseException ex) {
            log.error("Error occurred when tryConvert methods of DateConverter.");
            ex.printStackTrace();
            return null;
        }

    }

    /*****************************
     * 在当前日期的前提下加减时间
     *
     * @param value为正则往后
     *            ,为负则往前
     * @param field取1加1年,取2加月,取3加一季度,取4加一周 取5加一天...分钟12，
     * @return
     */
    public static String getDateAddOrSub(int field, int value,Date datetime) {
        String date = "";
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(datetime);
        gc.add(field, value);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        date = df.format(gc.getTime());
        return date;
    }


    /**
     * date转化String
     *
     * @param param
     */
    public static void date2String(Map<String, Object> param) {
        Set<String> set = param.keySet();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (String str : set) {
            if (param.get(str) instanceof Date) {
                param.put(str, format.format(param.get(str)));
            }
        }
    }

    /**
     * 日期格式化常量
     */
    public static final int STYLE1 = 0;// yyyy-MM-dd

    public static final int STYLE2 = 1;// yyyyMMdd

    public static final int STYLE3 = 2;// yyyy/MM/dd

    public static final int STYLE4 = 3;// yyyyMM

    public static final int STYLE5 = 4;// yyyy年MM月dd日

    public static final int STYLE6 = 5;// yyyy-MM-dd HH:mm:ss

    public static final int STYLE7 = 6;// yyyy-MM-dd HH:mm

    public static final int STYLE8 = 7;// yyyyMMddHH:mm

    public static final int STYLE9 = 8;// HH:mm

    public static final int STYLE10 = 9;// yyyyMMddHH:mm
    public static final int STYLE11 = 10;// yyyy-MM
    public static final int STYLE12 = 11;// yyyyMMddHHmmss


    /**
     * 返回指定格式的日期字符串
     *
     * @param date  日期
     * @param style 样式
     * @return
     */
    public static String getFormattedDate(Date date, int style) {
        String formatStyle = "";

        switch (style) {
            case STYLE1:
                formatStyle = "yyyy-MM-dd";
                break;
            case STYLE2:
                formatStyle = "yyyyMMdd";
                break;
            case STYLE3:
                formatStyle = "yyyy/MM/dd";
                break;
            case STYLE4:
                formatStyle = "yyyyMM";
                break;
            case STYLE5:
                formatStyle = "yyyy年MM月dd日";
                break;
            case STYLE6:
                formatStyle = "yyyy-MM-dd HH:mm:ss";
                break;
            case STYLE7:
                formatStyle = "yyyy-MM-dd HH:mm";
                break;
            case STYLE8:
            	formatStyle = "yyyyMMddHH:mm";
            	 break;
            case STYLE10:
                formatStyle = "yyMM";
                break;
            case STYLE11:
            	formatStyle = "yyyyMMddHHmmss";
            	 break;
        }
        DateFormat format = new SimpleDateFormat(formatStyle);
        if (date == null) {
            return "";
        }
        return format.format(date);
    }

    /**
     * 解析字符串为日期
     *
     * @param str   字符串
     * @param style 样式
     * @return
     */

    public static Date parseDate(String str, int style) {
        String formatStyle = "";

        switch (style) {
            case STYLE1:
                formatStyle = "yyyy-MM-dd";
                break;
            case STYLE2:
                formatStyle = "yyyyMMdd";
                break;
            case STYLE3:
                formatStyle = "yyyy/MM/dd";
                break;
            case STYLE4:
                formatStyle = "yyyyMM";
                break;
            case STYLE5:
                formatStyle = "yyyy年MM月dd日";
                break;
            case STYLE6:
                formatStyle = "yyyy-MM-dd HH:mm:ss";
                break;
            case STYLE7:
                formatStyle = "yyyy-MM-dd HH:mm";
                break;
            case STYLE9:
                formatStyle = "HH:mm";
                break;
            case   STYLE10:
                formatStyle = "yyMM";
                break;
            case   STYLE11:
                formatStyle = "yyyy-MM";
                break;

        }
        DateFormat format = new SimpleDateFormat(formatStyle);
        if (str != null) {
            try {
                Date date = format.parse(str);
//                Date date = format.parse(str);
                return date;
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    /**
     *
     * @param date
     * @param minute 正负时间浮动
     * @return
     */
    public static Date changeMinute(Date date,int minute){
        Calendar nowTime = Calendar.getInstance();
        nowTime.setTime(date);
        nowTime.add(Calendar.MINUTE, minute);
        return nowTime.getTime();
    }

    public static Date getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY,0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    public static Date getEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY,23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }



    public static String getDayofWeek(Date date){
        //"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六","星期日"
        String[] weekDays = {"7", "1", "2", "3", "4", "5", "6","7"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }


    public static String getDateString(Date date){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = sdf.format(date);
        return dateStr;
    }

    public static String getBeginningOfMonth(Date date){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM");
        String dateStr = sdf.format(date);
        return dateStr+"-01 00:00:00";
    }

    public static Boolean isHotTime(String datestring){
        Date date = parseDate(datestring, 5);

        String beginningOfMonth = getBeginningOfMonth(new Date());
        Date beginDate = parseDate(beginningOfMonth, 5);
        String dateAddOrSub = getDateAddOrSub(2, -3, beginDate);
        Date targetDate = parseDate(dateAddOrSub, 5);
        if(date.getTime()<targetDate.getTime()){
            return false;
        }else {
            return true;
        }
    }

    /**
     *
     * @param smdate start
     * @param bdate end
     * @return
     * @throws ParseException
     */

    /**
     * @param smdate start
     * @param bdate  end
     * @param type   0 Date 1 hour 2 minute
     * @return
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate, int type) {
        long between_days = 0;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            smdate = sdf.parse(sdf.format(smdate));
            bdate = sdf.parse(sdf.format(bdate));
            Calendar cal = Calendar.getInstance();
            cal.setTime(smdate);
            long time1 = cal.getTimeInMillis();
            cal.setTime(bdate);
            long time2 = cal.getTimeInMillis();
            switch (type) {
                case 0:
                    between_days = (time2 - time1) / (1000 * 3600 * 24);

                    break;
                case 1:
                    between_days = (time2 - time1) / (1000 * 3600);

                    break;
                case 2:
                    between_days = (time2 - time1) / (1000 * 60);

                    break;
                default:
                    break;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

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



    public  static  List<String> splitMonthList(Date startDate,Date endDate){
        List<String> listDate = new ArrayList<>();

        try {

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            // 获取开始年份和开始月份
            int startYear = calendar.get(Calendar.YEAR);
            int startMonth = calendar.get(Calendar.MONTH);
            // 获取结束年份和结束月份
            calendar.setTime(endDate);
            int endYear = calendar.get(Calendar.YEAR);
            int endMonth = calendar.get(Calendar.MONTH);
            //
            List<String> list = new ArrayList<String>();
            for (int i = startYear; i <= endYear; i++) {
                String date = "";
                if (startYear == endYear) {
                    for (int j = startMonth; j <= endMonth; j++) {
                        if (j < 9) {
                            date = i + "-0" + (j + 1);
                        } else {
                            date = i + "-" + (j + 1);
                        }
                        list.add(date);
                    }

                } else {
                    if (i == startYear) {
                        for (int j = startMonth; j < 12; j++) {
                            if (j < 9) {
                                date = i + "-0" + (j + 1);
                            } else {
                                date = i + "-" + (j + 1);
                            }
                            list.add(date);
                        }
                    } else if (i == endYear) {
                        for (int j = 0; j <= endMonth; j++) {
                            if (j < 9) {
                                date = i + "-0" + (j + 1);
                            } else {
                                date = i + "-" + (j + 1);
                            }
                            list.add(date);
                        }
                    } else {
                        for (int j = 0; j < 12; j++) {
                            if (j < 9) {
                                date = i + "-0" + (j + 1);
                            } else {
                                date = i + "-" + (j + 1);
                            }
                            list.add(date);
                        }
                    }

                }

            }

            // 所有的月份已经准备好
            //System.out.println(list);
            for(int i = 0;i < list.size();i++){
                listDate.add(list.get(i));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return listDate;

    }


    public static List<String> splitDateList(Date startDate, Date endDate) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> listDate = new ArrayList<>();
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            while (calendar.getTime().before(endDate) || calendar.getTime().equals(endDate)) {
                listDate.add(dateFormat.format(calendar.getTime()));
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
            return listDate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return listDate;
    }


    public static String nextDayOfWeek(int dow) {
        Calendar date = Calendar.getInstance();

        int cur = date.get(Calendar.DAY_OF_WEEK);
        int diff = dow - cur+1;
        if (diff <= 0) {
            diff += 7;
        }
        date.add(Calendar.DAY_OF_MONTH, diff);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = df.format(date.getTime());
        return dateString;
    }

    public static String getCurDayOfMonth() {
        Calendar date = Calendar.getInstance();
        Integer cur = date.get(Calendar.DAY_OF_MONTH);
        return cur.toString();
    }

    public static String nextDayOfMonth(int dow) {
        Calendar date = Calendar.getInstance();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        if(dow!=99){
            int diff = dow - date.get(Calendar.DAY_OF_MONTH);
            int maxDate = date.getActualMaximum(Calendar.DAY_OF_MONTH);
            System.out.println(maxDate);
            if (diff <= 0) {
                diff += maxDate;
            }
            date.add(Calendar.DAY_OF_MONTH, diff);
        }else{
            int maxDate = date.getActualMaximum(Calendar.DAY_OF_MONTH);
            date.set(Calendar.DAY_OF_MONTH,maxDate);

        }
        return df.format(date.getTime());

    }


    /**
     * 返回时间点大的时间
     * @param hour1
     * @param hour2
     * @return
     */
    public static String compareHourMinter(String hour1,String hour2){
        String[] split1 = hour1.split(":");
        String[] split2= hour2.split(":");
        if(Integer.parseInt(split1[0])>Integer.parseInt(split2[0])){
            return hour1;
        }else if(Integer.parseInt(split1[0])<Integer.parseInt(split2[0])){
            return hour2;

        }else{
            if(Integer.parseInt(split1[1])>Integer.parseInt(split2[1])){
                return hour1;
            }else{
                return hour2;
            }
        }
    }
}
