package com.yxcheng.token.utils;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.util.StringUtils;

import java.beans.PropertyEditorSupport;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class DateUtils extends PropertyEditorSupport {
	// 各种时间格式
	public static final SimpleDateFormat date_sdf = new SimpleDateFormat(
			"yyyy-MM-dd");
	// 各种时间格式
	public static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat(
			"yyyyMMdd");
	public static final SimpleDateFormat yyyyMM = new SimpleDateFormat(
			"yyyyMM");
	// 各种时间格式
	public static final SimpleDateFormat date_sdf_wz = new SimpleDateFormat(
			"yyyy年MM月dd日");
	public static final SimpleDateFormat time_sdf = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm");
	public static final SimpleDateFormat yyyymmddhhmmss = new SimpleDateFormat(
	"yyyyMMddHHmmss");
    public static final SimpleDateFormat yyyymmddhh = new SimpleDateFormat(
            "yyyyMMddHH");
	public static final SimpleDateFormat short_time_sdf = new SimpleDateFormat(
			"HH:mm");
	public static final  SimpleDateFormat datetimeFormat = new SimpleDateFormat(
	"yyyy-MM-dd HH:mm:ss");

	public static final  SimpleDateFormat yyyymmddthhmmssz = new SimpleDateFormat(
			"yyyy-MM-dd'T'HH:mm:ss'Z'");

	public static final  SimpleDateFormat yyyymmddthhmmssSSS = new SimpleDateFormat(
			"yyyyMMddHHmmssSSS");
    public static final SimpleDateFormat date_sdf_s = new SimpleDateFormat(
            "/yyyy/MM/dd/");
	// 以毫秒表示的时间
	private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
	private static final long HOUR_IN_MILLIS = 3600 * 1000;
	private static final long MINUTE_IN_MILLIS = 60 * 1000;
	private static final long SECOND_IN_MILLIS = 1000;
	// 指定模式的时间格式
	private static SimpleDateFormat getSDFormat(String pattern) {
		return new SimpleDateFormat(pattern);
	}

	/**
	 * 当前日历，这里用中国时间表示
	 * 
	 * @return 以当地时区表示的系统当前日历
	 */
	public static Calendar getCalendar() {
		return Calendar.getInstance();
	}

	/**
	 * 指定毫秒数表示的日历
	 * 
	 * @param millis
	 *            毫秒数
	 * @return 指定毫秒数表示的日历
	 */
	public static Calendar getCalendar(long millis) {
		Calendar cal = Calendar.getInstance();
		// --------------------cal.setTimeInMillis(millis);
		cal.setTime(new Date(millis));
		return cal;
	}

	// ////////////////////////////////////////////////////////////////////////////
	// getDate
	// 各种方式获取的Date
	// ////////////////////////////////////////////////////////////////////////////

	/**
	 * 当前日期
	 * 
	 * @return 系统当前时间
	 */
	public static Date getDate() {
		return new Date();
	}

	public static Date toDate(String pattern){
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        String dateString = formatter.format(getDate());
        try {
            Date parse = formatter.parse(dateString);
            return parse;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static Date toDate(Date date,String pattern){
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        String dateString = formatter.format(date);
        try {
            Date parse = formatter.parse(dateString);
            return parse;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

	public static Date toDate(Date date,SimpleDateFormat formatter){
		String dateString = formatter.format(date);
		try {
			Date parse = formatter.parse(dateString);
			return parse;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 指定毫秒数表示的日期
	 * 
	 * @param millis
	 *            毫秒数
	 * @return 指定毫秒数表示的日期
	 */
	public static Date getDate(long millis) {
		return new Date(millis);
	}

	/**
	 * 时间戳转换为字符串
	 * 
	 * @param time
	 * @return
	 */
	public static String timestamptoStr(Timestamp time) {
		Date date = null;
		if (null != time) {
			date = new Date(time.getTime());
		}
		return date2Str(date_sdf);
	}

	/**
	 * 字符串转换时间戳
	 * 
	 * @param str
	 * @return
	 */
	public static Timestamp str2Timestamp(String str) {
		Date date = str2Date(str, date_sdf);
		return new Timestamp(date.getTime());
	}
	/**
	 * 字符串转换成日期
	 * @param str
	 * @param sdf
	 * @return
	 */
	public static Date str2Date(String str, SimpleDateFormat sdf) {
		if (null == str || "".equals(str)) {
			return null;
		}
		Date date = null;
		try {
			date = sdf.parse(str);
			return date;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 日期转换为字符串
	 *            日期格式
	 * @return 字符串
	 */
	public static String date2Str(SimpleDateFormat date_sdf) {
		Date date=getDate();
		if (null == date) {
			return null;
		}
		return date_sdf.format(date);
	}
	/**
	 * 格式化时间
	 * @param date
	 * @param format
	 * @return
	 */
	public static String dateformat(String date,String format)
	{
		SimpleDateFormat sformat = new SimpleDateFormat(format);
		Date _date=null;
		try {
			 _date=sformat.parse(date);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sformat.format(_date);
	}
	/**
	 * 日期转换为字符串
	 * 
	 * @param date
	 *            日期
	 * @param
	 * @return 字符串
	 */
	public static String date2Str(Date date, SimpleDateFormat date_sdf) {
		if (null == date) {
			return null;
		}
		return date_sdf.format(date);
	}
	/**
	 * 日期转换为字符串
	 * 
	 * @param
	 *
	 * @param format
	 *            日期格式
	 * @return 字符串
	 */
	public static String getDate(String format) {
		Date date=new Date();
		if (null == date) {
			return null;
		}

		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}

	/**
	 * 指定毫秒数的时间戳
	 * 
	 * @param millis
	 *            毫秒数
	 * @return 指定毫秒数的时间戳
	 */
	public static Timestamp getTimestamp(long millis) {
		return new Timestamp(millis);
	}

	/**
	 * 以字符形式表示的时间戳
	 * 
	 * @param time
	 *            毫秒数
	 * @return 以字符形式表示的时间戳
	 */
	public static Timestamp getTimestamp(String time) {
		return new Timestamp(Long.parseLong(time));
	}

	/**
	 * 系统当前的时间戳
	 * 
	 * @return 系统当前的时间戳
	 */
	public static Timestamp getTimestamp() {
		return new Timestamp(new Date().getTime());
	}

	/**
	 * 指定日期的时间戳
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的时间戳
	 */
	public static Timestamp getTimestamp(Date date) {
		return new Timestamp(date.getTime());
	}

	/**
	 * 指定日历的时间戳
	 * 
	 * @param cal
	 *            指定日历
	 * @return 指定日历的时间戳
	 */
	public static Timestamp getCalendarTimestamp(Calendar cal) {
		// ---------------------return new Timestamp(cal.getTimeInMillis());
		return new Timestamp(cal.getTime().getTime());
	}

	public static Timestamp gettimestamp() {
		Date dt = new Date();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String nowTime = df.format(dt);
		Timestamp buydate = Timestamp.valueOf(nowTime);
		return buydate;
	}

	// ////////////////////////////////////////////////////////////////////////////
	// getMillis
	// 各种方式获取的Millis
	// ////////////////////////////////////////////////////////////////////////////

	/**
	 * 系统时间的毫秒数
	 * 
	 * @return 系统时间的毫秒数
	 */
	public static long getMillis() {
		return new Date().getTime();
	}

	/**
	 * 指定日历的毫秒数
	 * 
	 * @param cal
	 *            指定日历
	 * @return 指定日历的毫秒数
	 */
	public static long getMillis(Calendar cal) {
		// --------------------return cal.getTimeInMillis();
		return cal.getTime().getTime();
	}

	/**
	 * 指定日期的毫秒数
	 * 
	 * @param date
	 *            指定日期
	 * @return 指定日期的毫秒数
	 */
	public static long getMillis(Date date) {
		return date.getTime();
	}

	/**
	 * 指定时间戳的毫秒数
	 * 
	 * @param ts
	 *            指定时间戳
	 * @return 指定时间戳的毫秒数
	 */
	public static long getMillis(Timestamp ts) {
		return ts.getTime();
	}

	// ////////////////////////////////////////////////////////////////////////////
	// formatDate
	// 将日期按照一定的格式转化为字符串
	// ////////////////////////////////////////////////////////////////////////////

	/**
	 * 默认方式表示的系统当前日期，具体格式：年-月-日
	 * 
	 * @return 默认日期按“年-月-日“格式显示
	 */
	public static String formatDate() {
		return date_sdf.format(getCalendar().getTime());
	}
	/**
	 * 获取时间字符串
	 */
	public static String getDataString(SimpleDateFormat formatstr) {
		return formatstr.format(getCalendar().getTime());
	}
	/**
	 * 指定日期的默认显示，具体格式：年-月-日
	 * 
	 * @param cal
	 *            指定的日期
	 * @return 指定日期按“年-月-日“格式显示
	 */
	public static String formatDate(Calendar cal) {
		return date_sdf.format(cal.getTime());
	}

	/**
	 * 指定日期的默认显示，具体格式：年-月-日
	 * 
	 * @param date
	 *            指定的日期
	 * @return 指定日期按“年-月-日“格式显示
	 */
	public static String formatDate(Date date) {
		return date_sdf.format(date);
	}

	/**
	 * 指定毫秒数表示日期的默认显示，具体格式：年-月-日
	 * 
	 * @param millis
	 *            指定的毫秒数
	 * @return 指定毫秒数表示日期按“年-月-日“格式显示
	 */
	public static String formatDate(long millis) {
		return date_sdf.format(new Date(millis));
	}

    public static String formatDate(long millis,SimpleDateFormat date_sdf) {
        return date_sdf.format(new Date(millis));
    }


	/**
	 * 默认日期按指定格式显示
	 * 
	 * @param pattern
	 *            指定的格式
	 * @return 默认日期按指定格式显示
	 */
	public static String formatDate(String pattern) {
		return getSDFormat(pattern).format(getCalendar().getTime());
	}

	/**
	 * 指定日期按指定格式显示
	 * 
	 * @param cal
	 *            指定的日期
	 * @param pattern
	 *            指定的格式
	 * @return 指定日期按指定格式显示
	 */
	public static String formatDate(Calendar cal, String pattern) {
		return getSDFormat(pattern).format(cal.getTime());
	}

	/**
	 * 指定日期按指定格式显示
	 * 
	 * @param date
	 *            指定的日期
	 * @param pattern
	 *            指定的格式
	 * @return 指定日期按指定格式显示
	 */
	public static String formatDate(Date date, String pattern) {
		return getSDFormat(pattern).format(date);
	}

	// ////////////////////////////////////////////////////////////////////////////
	// formatTime
	// 将日期按照一定的格式转化为字符串
	// ////////////////////////////////////////////////////////////////////////////

	/**
	 * 默认方式表示的系统当前日期，具体格式：年-月-日 时：分
	 * 
	 * @return 默认日期按“年-月-日 时：分“格式显示
	 */
	public static String formatTime() {
		return time_sdf.format(getCalendar().getTime());
	}

	/**
	 * 指定毫秒数表示日期的默认显示，具体格式：年-月-日 时：分
	 * 
	 * @param millis
	 *            指定的毫秒数
	 * @return 指定毫秒数表示日期按“年-月-日 时：分“格式显示
	 */
	public static String formatTime(long millis) {
		return time_sdf.format(new Date(millis));
	}

	/**
	 * 指定日期的默认显示，具体格式：年-月-日 时：分
	 * 
	 * @param cal
	 *            指定的日期
	 * @return 指定日期按“年-月-日 时：分“格式显示
	 */
	public static String formatTime(Calendar cal) {
		return time_sdf.format(cal.getTime());
	}

	/**
	 * 指定日期的默认显示，具体格式：年-月-日 时：分
	 * 
	 * @param date
	 *            指定的日期
	 * @return 指定日期按“年-月-日 时：分“格式显示
	 */
	public static String formatTime(Date date) {
		return time_sdf.format(date);
	}

	// ////////////////////////////////////////////////////////////////////////////
	// formatShortTime
	// 将日期按照一定的格式转化为字符串
	// ////////////////////////////////////////////////////////////////////////////

	/**
	 * 默认方式表示的系统当前日期，具体格式：时：分
	 * 
	 * @return 默认日期按“时：分“格式显示
	 */
	public static String formatShortTime() {
		return short_time_sdf.format(getCalendar().getTime());
	}

	/**
	 * 指定毫秒数表示日期的默认显示，具体格式：时：分
	 * 
	 * @param millis
	 *            指定的毫秒数
	 * @return 指定毫秒数表示日期按“时：分“格式显示
	 */
	public static String formatShortTime(long millis) {
		return short_time_sdf.format(new Date(millis));
	}

	/**
	 * 指定日期的默认显示，具体格式：时：分
	 * 
	 * @param cal
	 *            指定的日期
	 * @return 指定日期按“时：分“格式显示
	 */
	public static String formatShortTime(Calendar cal) {
		return short_time_sdf.format(cal.getTime());
	}

	/**
	 * 指定日期的默认显示，具体格式：时：分
	 * 
	 * @param date
	 *            指定的日期
	 * @return 指定日期按“时：分“格式显示
	 */
	public static String formatShortTime(Date date) {
		return short_time_sdf.format(date);
	}

	// ////////////////////////////////////////////////////////////////////////////
	// parseDate
	// parseCalendar
	// parseTimestamp
	// 将字符串按照一定的格式转化为日期或时间
	// ////////////////////////////////////////////////////////////////////////////

	/**
	 * 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间
	 * 
	 * @param src
	 *            将要转换的原始字符窜
	 * @param pattern
	 *            转换的匹配格式
	 * @return 如果转换成功则返回转换后的日期
	 * @throws ParseException
	 */
	public static Date parseDate(String src, String pattern)
			throws ParseException {
		return getSDFormat(pattern).parse(src);

	}

	/**
	 * 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间
	 * 
	 * @param src
	 *            将要转换的原始字符窜
	 * @param pattern
	 *            转换的匹配格式
	 * @return 如果转换成功则返回转换后的日期
	 * @throws ParseException
	 */
	public static Calendar parseCalendar(String src, String pattern)
			throws ParseException {

		Date date = parseDate(src, pattern);
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal;
	}

	public static String formatAddDate(String src, String pattern, int amount)
			throws ParseException {
		Calendar cal;
		cal = parseCalendar(src, pattern);
		cal.add(Calendar.DATE, amount);
		return formatDate(cal);
	}

	/**
	 * 根据指定的格式将字符串转换成Date 如输入：2003-11-19 11:20:20将按照这个转成时间
	 * 
	 * @param src
	 *            将要转换的原始字符窜
	 * @param pattern
	 *            转换的匹配格式
	 * @return 如果转换成功则返回转换后的时间戳
	 * @throws ParseException
	 * @throws
	 */
	public static Timestamp parseTimestamp(String src, String pattern)
			throws ParseException {
		Date date = parseDate(src, pattern);
		return new Timestamp(date.getTime());
	}

	// ////////////////////////////////////////////////////////////////////////////
	// dateDiff
	// 计算两个日期之间的差值
	// ////////////////////////////////////////////////////////////////////////////

	/**
	 * 计算两个时间之间的差值，根据标志的不同而不同
	 * 
	 * @param flag
	 *            计算标志，表示按照年/月/日/时/分/秒等计算
	 * @param calSrc
	 *            减数
	 * @param calDes
	 *            被减数
	 * @return 两个日期之间的差值
	 */
	public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {

		long millisDiff = getMillis(calSrc) - getMillis(calDes);

		if (flag == 'y') {
			return (calSrc.get(calSrc.YEAR) - calDes.get(calDes.YEAR));
		}

		if (flag == 'd') {
			return (int) (millisDiff / DAY_IN_MILLIS);
		}

		if (flag == 'h') {
			return (int) (millisDiff / HOUR_IN_MILLIS);
		}

		if (flag == 'm') {
			return (int) (millisDiff / MINUTE_IN_MILLIS);
		}

		if (flag == 's') {
			return (int) (millisDiff / SECOND_IN_MILLIS);
		}

		return 0;
	}

    public static Date getNationDate(String nationCycle) {
        return getNationDate(nationCycle,new Date());
    }

    public static Date[] getNationDates(String nationCycle) {
	    return getNationDates(nationCycle,new Date());
    }




    public static Date getPreApplyDate(Date date,String preApplyRange) {
        if(org.apache.commons.lang.StringUtils.isBlank(preApplyRange)) return date;

        int preApplyRangeInt = Integer.valueOf(preApplyRange);
        if(preApplyRangeInt<=0) return date;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day = calendar.get(Calendar.DATE);
        if(day-preApplyRangeInt < 1){
            calendar.set(Calendar.DATE,1);
        }else {
            calendar.set(Calendar.DATE, day - preApplyRangeInt);
        }
        return calendar.getTime();
    }

    /**
     * 通过日期算当前属于第几周期，生成开始结束日期，如果为null，应执行上个月遗留数据
     * @param nationCycle
     * @param now
     * @return
     */
    public static Date[] getNationDates(String nationCycle,Date now) {
        int cycle = Integer.valueOf(nationCycle);

        int dayCycle = getDayCycle(nationCycle,now);
        if(dayCycle <= 0) return null;


        Date[] dates = new Date[2];
        Calendar calendarStart = Calendar.getInstance();
        calendarStart.setTime(now);
        calendarStart.set(Calendar.DATE,(cycle * (dayCycle - 1) + 1));
        dates[0] = calendarStart.getTime();

        Calendar calendarEnd = Calendar.getInstance();
        calendarEnd.setTime(now);
        calendarEnd.set(Calendar.DATE,(cycle * dayCycle));
        dates[1] = calendarEnd.getTime();

        return dates;
    }

    public static int getDayCycle(String nationCycle,Date now){
        int cycle = Integer.valueOf(nationCycle);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
        int day = calendar.get(Calendar.DATE);
        int dayCycle = day/cycle;

        int modular = day % cycle;
        if(modular==0){
            dayCycle--;
        }
        return dayCycle;
    }

    public static Date getNationDate(String nationCycle,Date date) {
        int cycle = Integer.valueOf(nationCycle) - 1;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if(calendar.get(Calendar.DATE)<=cycle){
            calendar.set(Calendar.DAY_OF_MONTH,1);
            calendar.add(Calendar.MONTH, 0);
        }else {
            calendar.add(Calendar.DAY_OF_MONTH, -cycle);
        }
        return calendar.getTime();
    }


    public static Date getNationDateNoMonthLimit(String nationCycle,Date date) {
        int cycle = Integer.valueOf(nationCycle) - 1;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -cycle);
        return calendar.getTime();
    }

    public static Date getPastDate(int past) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
        return calendar.getTime();
    }

	public static Date getDateMoveHour(int moveHours) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - moveHours);
		return calendar.getTime();
	}

    public static int monthCompare(Date date1,Date date2){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String str1 = sdf.format(date1);
        String str2 = sdf.format(date2);
        Calendar bef = Calendar.getInstance();
        Calendar aft = Calendar.getInstance();
        try {
            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);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return -1;
    }

    public static int dateCompare(Date date1, Date date2) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateFirst = dateFormat.format(date1);
        String dateLast = dateFormat.format(date2);
        int dateFirstIntVal = Integer.parseInt(dateFirst);
        int dateLastIntVal = Integer.parseInt(dateLast);
        if (dateFirstIntVal > dateLastIntVal) {
            return 1;
        } else if (dateFirstIntVal < dateLastIntVal) {
            return -1;
        }
        return 0;
    }

    public static int dayCompare(Date date1,Date date2){
    	int dayDiff = -1;
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");

        try {
            date1=sdf.parse(sdf.format(date1));
            date2=sdf.parse(sdf.format(date2));

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

            long time1 = cal.getTimeInMillis();
            cal.setTime(date2);

            long time2 = cal.getTimeInMillis();
            long between_days=(time2-time1)/(1000*3600*24);
            dayDiff = Integer.parseInt(String.valueOf(between_days));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dayDiff;
    }

    public static Date getApplyStartDate(Date preDateEnd, String applyCycle) {
        Integer cycle = Integer.valueOf(applyCycle);
        int day = DateUtils.getDay(preDateEnd);
        int resultDay = 0;
        for(int i=0;i<32;i++){

            if((resultDay+cycle)>=day){
                break;
            }
            resultDay += cycle;
        }

        Date tmp = preDateEnd;
        return DateUtils.replaceDay(tmp,resultDay + 1);
    }



    public static Date getPreFirstDay(Date date,int i){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        calendar.add(Calendar.MONTH, -i);
        return calendar.getTime();
    }

    public static Date getPreLastDay(Date date,int i){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -(i-1));
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        return calendar.getTime();
    }

    public static int getApplyFixDays(Date date,String applyCycle) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day = calendar.get(Calendar.DATE);
        return Integer.valueOf(applyCycle) - day;
    }

    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    public static String getDayStr(Date date) {
        String sDay = "";
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int iDay = calendar.get(Calendar.DAY_OF_MONTH);
        if(iDay<10) {
            sDay = "0" + iDay;
        } else {
            sDay = Integer.toString(iDay);
        }
        return sDay;
    }

    public static Date replaceDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,day);
        return calendar.getTime();
    }

    public static boolean isCommonDayCycle(String nationCycle,Date applyDownDate) {
        if(applyDownDate == null) return false;

        int lastCycle = DateUtils.getDayCycle(nationCycle, applyDownDate);
        int nowCycle = DateUtils.getDayCycle(nationCycle, new Date());

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(applyDownDate);
        int month = calendar.get(Calendar.MONTH);
        int year = calendar.get(Calendar.YEAR);

        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(new Date());
        int nowMonth = calendar1.get(Calendar.MONTH);
        int nowYear = calendar1.get(Calendar.YEAR);


        if(year == nowYear && nowMonth == month  && lastCycle == nowCycle) return true;
        return false;
    }


    /**
     * String类型 转换为Date,
     * 如果参数长度为10 转换格式”yyyy-MM-dd“
     *如果参数长度为19 转换格式”yyyy-MM-dd HH:mm:ss“
     * * @param text
	 *             String类型的时间值
     */
	public void setAsText(String text) throws IllegalArgumentException {
		if (StringUtils.hasText(text)) {
			try {
				if (text.indexOf(":") == -1 && text.length() == 10) {
					setValue(this.date_sdf.parse(text));
				} else if (text.indexOf(":") > 0 && text.length() == 19) {
					setValue(this.datetimeFormat.parse(text));
				} else {
					throw new IllegalArgumentException(
							"Could not parse date, date format is error ");
				}
			} catch (ParseException ex) {
				IllegalArgumentException iae = new IllegalArgumentException(
						"Could not parse date: " + ex.getMessage());
				iae.initCause(ex);
				throw iae;
			}
		} else {
			setValue(null);
		}
	}
	public static int getYear(){
	    GregorianCalendar calendar=new GregorianCalendar();
	    calendar.setTime(getDate());
	    return calendar.get(Calendar.YEAR);
	  }
	public static int getYear(Date date){
	    GregorianCalendar calendar=new GregorianCalendar();
	    calendar.setTime(date);
	    return calendar.get(Calendar.YEAR);
	  }
	
	 /**
     * 获取当年的第一天
     * @return
     */
    public static Date getCurrYearFirst(){
        Calendar currCal=Calendar.getInstance();  
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }
    /**
     * 获取明年的第一天
     * @return
     */
    public static Date getNextYearFirst(){
        Calendar currCal=Calendar.getInstance();  
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear+1);
    }
     
    /**
     * 获取当年的最后一天
     * @return
     */
    public static Date getCurrYearLast(){
        Calendar currCal=Calendar.getInstance();  
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearLast(currentYear);
    }
     
    /**
     * 获取某年第一天日期
     * @param year 年份
     * @return Date
     */
    public static Date getYearFirst(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }
     
    /**
     * 获取某年最后一天日期
     * @param year 年份
     * @return Date
     */
    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 dateStr yyyyMM
     * @return String
     */
    public static String getMonthLastByStr(String dateStr){
    	SimpleDateFormat mat = new SimpleDateFormat("yyyyMM");
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
    	Calendar ca = Calendar.getInstance();   
    	try {
			ca.setTime(mat.parse(dateStr));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));  
        String last = format.format(ca.getTime());
        return last;
    }
    
    /**
     * 获取某月最后一天日期
     * @return String
     */
    public static String getMonthLast(){
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
    	Calendar ca = Calendar.getInstance();    
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));  
        String last = format.format(ca.getTime());
        return last;
    }
    
    /**
     * 获取当月第一天日期
     * @return String
     */
    public static String getMonthFirst(){
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
    	Calendar c = Calendar.getInstance();    
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
        String first = format.format(c.getTime());
        return first;
    }
    
    /**
     * 获取某月第一天日期
     * @param dateStr yyyyMM
     * @return String
     */
    public static String getMonthFirstByStr(String dateStr){
    	SimpleDateFormat mat = new SimpleDateFormat("yyyyMM");
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
    	Calendar c = Calendar.getInstance();    
    	try {
			c.setTime(mat.parse(dateStr));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
        String first = format.format(c.getTime());
        return first;
    }
    
    public static String getPastMonthFirst(){
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
    	Calendar c = Calendar.getInstance();    
        c.add(Calendar.MONTH, -1);
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
        String first = format.format(c.getTime());
        return first;
    }
    
    public static String getYear(String date) {
    	String year = "";
    	try {
    		year = String.valueOf(getYear(parseDate(date, "yyyy-MM-dd")));
		} catch (ParseException e) {
		}
    	return year;
    }
	public static Date addDate(Date date, int amount){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, amount);
        return cal.getTime();
    }

	public static Date addSecond(Date date, int amount){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.SECOND, amount);
		return cal.getTime();
	}

    public static Date addMonth(Date date, int amount){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, amount);
        return cal.getTime();
    }

    public static Date toDayStart(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH),
                0, 0, 0);
        return calendar.getTime();
    }

    public static Date toDayEnd(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH),
                23, 59, 59);
        return calendar.getTime();
    }

    public static String getTodayStr(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String nowStr = sdf.format(new Date());
        return nowStr;
    }

    public static boolean isToday(Date date){
        SimpleDateFormat fmt=new SimpleDateFormat("yyyy-MM-dd");
        if(fmt.format(date).toString().equals(fmt.format(new Date()).toString())){//格式化为相同格式
            return true;
        }else {
            return false;
        }
    }

	public static Date getSearchDate(String sDate){
		return str2Date(sDate,date_sdf);
	}

    public static Date getDetailDate(String sDate){
        return str2Date(sDate,datetimeFormat);
    }


    public static long getDiff(Date originDate,Date currentDate){
        long sTime = originDate.getTime();
        long cTime = currentDate.getTime();
        return sTime - cTime;
    }

	public static Date getSearchDateAdd1(String sDate){
		return addDate(str2Date(sDate,date_sdf),1);
	}

    public static String strToDateFormat(String date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        formatter.setLenient(false);
        Date newDate= null;
        try {
            newDate = formatter.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        formatter = new SimpleDateFormat("yyyy-MM-dd");
        return formatter.format(newDate);
    }

    /**
     * 返回一个当前的时间，并按格式转换为字符串
     * 
     * @return String
     */
    public static String getDateTime(String... pattern){   

//        GregorianCalendar gcNow = new GregorianCalendar();
//        return DateFormatUtils.format(gcNow,pattern);
    	String sPtn = "yyyy-MM-dd HH:mm:ss";
		if (pattern != null&&pattern.length>0) {
			sPtn = pattern[0];
		}	
        SimpleDateFormat  formatter = new SimpleDateFormat (sPtn);
        return formatter.format(new Date());
    }

    public static String toChinese(String dateString){
        String s_nd = dateString.substring(0, 4); // 年份
        String s_yf = dateString.substring(5, 7); // 月份
        String s_rq = dateString.substring(8, 10);
        return s_nd + "年" + s_yf + "月" + s_rq + "日";
    }

        public static List<String> getDayListByMonth(String month){
    	List<String> dayList = Lists.newArrayList();
		SimpleDateFormat mat = new SimpleDateFormat("yyyyMM");
		Calendar c = Calendar.getInstance();
		try {
			c.setTime(mat.parse(month));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		c.add(Calendar.MONTH, 0);
		int day = c.getActualMaximum(Calendar.DATE);
		for (int i = 1; i <= day; i++) {
			String dayStr = String.valueOf(i);
			dayList.add(dayStr.length()<2?("0" + dayStr):dayStr);
		}
		return dayList;
	}

	public static List<String> getDayList(int dayNum){
		List<String> dayList = Lists.newArrayList();
		for (int i = 1; i <= dayNum; i++) {
			String dayStr = String.valueOf(i);
			dayList.add(dayStr.length()<2?("0" + dayStr):dayStr);
		}
		return dayList;
	}

	public static String getYesterDay(){
        Calendar   cal   =   Calendar.getInstance();
        cal.add(Calendar.DATE,   -1);
        String yesterday = new SimpleDateFormat( "yyyy-MM-dd ").format(cal.getTime());
        return yesterday;
    }

	
	  /** 
	    * @Title: 获取月的天数 
	    * @Description: TODO(这里用一句话描述这个方法的作用) 
	    * @param @param dateStr
	    * @param @return    设定文件 
	    * @return int    返回类型 
	    * @throws 
	    */
	    public static int getMonthDays(String dateStr){
	    	 Calendar calendar = Calendar.getInstance();
	     	try {
	 			calendar.setTime(new SimpleDateFormat("yyyyMM").parse(dateStr));
	 		} catch (ParseException e) {
	 			// TODO Auto-generated catch block
	 			e.printStackTrace();
	 		}
	     	calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),1);
	     	calendar.roll(Calendar.DATE, false);
	     	return calendar.get(Calendar.DATE);
	     }

	/**
	 * 验证日期格式
	 * @param str
	 * @param pattern
	 * @return
	 */
	public static boolean isValidDate(String str,String pattern) {
		boolean convertSuccess=true;
		// 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		try {
			// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
			format.setLenient(false);
			format.parse(str);
		} catch (ParseException e) {
			// e.printStackTrace();
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			convertSuccess=false;
		}
		return convertSuccess;
	}

	public static boolean isBeyondOneYear(Date d) {
		Date now = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(d);
		c.add(Calendar.YEAR,1);
		Date proxyNow = c.getTime();
		return now.after(proxyNow);
	}
	
	/**
	 * 得到几天前的时间
	 * 
	 * @param d
	 * @param day
	 * @return
	 */
	public static Date getDateBefore(Date d, int day) {
		Calendar no = Calendar.getInstance();
		no.setTime(d);
		no.set(Calendar.DATE, no.get(Calendar.DATE) - day);
		return no.getTime();
	}


    public static boolean isInTheTime(Date d1, Date d2,int seconds){
        if(d1 == null || d2 == null){
            return false;
        }
        return ((d1.getTime() - d2.getTime())/1000) < seconds;
    }
    
    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     * 
     * @param nowTime 当前时间
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     * @author bree
     */
    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;
        }
    }
    //计算两个日期差多少小时
    public static long getDatePoor(Date startDate, Date endDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // 获得两个时间的毫秒时间差异
        long diff = startDate.getTime() - endDate.getTime();
        // 计算差多少小时
        long hour = diff % nd / nh;
        return hour;
    }

    public static long getDaySub(Date beginDate, Date endDate) {
        long day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
        return day;
    }

	public static long getHourSub(Date beginDate, Date endDate) {
		long hour = (endDate.getTime() - beginDate.getTime()) / (60 * 60 * 1000);
		return hour;
	}

	public static String getMonth(Date date) {
        return formatDate(date, "yyyyMM");
	}

    public static int getMinValue(Date now, String cycle) {
        Date applyDate = DateUtils.getPreFirstDay(now, 0);
        int minValue = 0;
        if(DateUtils.dayCompare(applyDate, now)< Integer.parseInt(cycle)) {
            minValue = 1;
        }
        return minValue;
    }

    public static boolean isCurMonth(Date date) {
        String oldMonth = formatDate(date, "yyyyMM");
        String curMonth = formatDate(getDate(), "yyyyMM");
        return oldMonth.equals(curMonth);
    }

    public static boolean isLastDayByMonth(Date date) {
        String oldInvMonth = DateUtils.getMonth(date);
        String lastDayStr = DateUtils.getMonthLastByStr(oldInvMonth);
        String curDayStr = DateUtils.date2Str(date, DateUtils.date_sdf);
        return lastDayStr.equals(curDayStr);
    }

    public static String getPastMonth(String yearMonth, int moveValue) {
        Date date = DateUtils.str2Date(yearMonth, new SimpleDateFormat("yyyyMM"));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + moveValue);
        return DateUtils.date2Str(calendar.getTime(), new SimpleDateFormat("yyyyMM"));
    }

    public static String getMonthFirst(String str, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        Calendar c = Calendar.getInstance();
        try {
            c.setTime(format.parse(str));
            c.add(Calendar.MONTH, 0);
            c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
            String first = format.format(c.getTime());
            return first;

        } catch (ParseException e) {
            e.printStackTrace();
            return str;
        }

    }

    public static Map<Date, Date> getApplyDateList(Date curDate, String applyCycle) {
        Map<Date, Date> applyDateList = Maps.newLinkedHashMap();
        Integer cycle = Integer.valueOf(applyCycle);
        int day = DateUtils.getMonthDays(DateUtils.getMonth(curDate));
        if(day <= cycle) {
            cycle = day;
        }
        Date firstDate = DateUtils.getPreFirstDay(curDate, 0);
        Date lastDate = DateUtils.getPreLastDay(curDate, 0);
        int num = day/cycle;
        for(int i=0;i<=num;i++) {
            Date endDate = DateUtils.addDate(firstDate, cycle-1);
            if(DateUtils.dateCompare(endDate, lastDate)==1) {
                endDate = lastDate;
            }
            applyDateList.put(firstDate, endDate);
            firstDate = DateUtils.addDate(endDate, 1);
            if(DateUtils.dateCompare(firstDate, lastDate)==1) {
                break;
            }
        }
        return applyDateList;
    }

    public static int compareYm(Date oDate, Date nDate) {
        Date ooDate = DateUtils.getPreFirstDay(oDate, 0);
		Date nnDate = DateUtils.getPreFirstDay(nDate, 0);
        return DateUtils.dateCompare(ooDate, nnDate);
    }

	public static Date getPreDateCurMonth(Date curDate, String applyCycle) {
		Integer cycle = Integer.valueOf(applyCycle);
		Date applyDate = DateUtils.getPreFirstDay(curDate, 0);
		int dayNum = DateUtils.dayCompare(applyDate, curDate);
		int cycleNum = dayNum/cycle;
		if(cycleNum == 0) {
			applyDate = DateUtils.getPreLastDay(curDate, 1);
		} else {
			applyDate = DateUtils.addDate(applyDate, cycle * cycleNum - 1);
		}
		return applyDate;
	}

	public static int getMinutesDiff(Date startDate, Date endDate) {
		int minutes = 0;
		try {
			long from = startDate.getTime();
			long to = endDate.getTime();
			minutes = (int) ((to - from)/(1000 * 60));
		} catch (Exception e) {
		}
		return minutes;
	}

    public static int getSecondsDiff(Date startDate, Date endDate) {
		int minutes = 0;
		try {
			long from = startDate.getTime();
			long to = endDate.getTime();
			minutes = (int) ((to - from)/1000);
		} catch (Exception e) {
		}
		return minutes;
	}

	public static int getMillSecondsDiff(Date startDate, Date endDate) {
		int minutes = 0;
		try {
			long from = startDate.getTime();
			long to = endDate.getTime();
			minutes = (int) (to - from);
		} catch (Exception e) {
		}
		return minutes;
	}

    public static int getDaysOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

	public static int getMonthSpace(Date date1, Date date2) {
		int result = 0;
		try {
			Calendar calendar1 = Calendar.getInstance();
			calendar1.setTime(date1);
			Calendar calendar2 = Calendar.getInstance();
			calendar2.setTime(date2);
			result = (calendar1.get(Calendar.YEAR) - calendar2.get(Calendar.YEAR)) * 12 + calendar1.get(Calendar.MONTH)
					- calendar2.get(Calendar.MONTH);
			result = result == 0 ? 1 : Math.abs(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}


    private static ThreadLocal<SimpleDateFormat> local = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    public static String format(Date date) {
        return local.get().format(date);
    }

    public static Date parse(String dateStr) throws ParseException {
        return local.get().parse(dateStr);
    }

    public static boolean companyCurDay(String cfgDay) {
        int curDay = DateUtils.getDay(DateUtils.getDate());
        if(curDay<Integer.parseInt(cfgDay)) {
            return true;
        }
        return false;
    }

	public static void main(String[] args) throws ParseException {
        Date dateStr = DateUtils.str2Date("2022-04-01", DateUtils.date_sdf);
		Date dateStrEnd = DateUtils.str2Date("2021-11-22", DateUtils.date_sdf);
        String nationCycle = "8";
        String month = DateUtils.getPastMonth("202105", 2);
		System.out.println(DateUtils.dayCompare(dateStr, DateUtils.getDate()));
        System.out.println(DateUtils.companyCurDay("22"));
        System.out.println(DateUtils.getDay(dateStr));
//		System.out.println(DateUtils.getMonthFirstByStr(month));
//        System.out.println(DateUtils.getMonthFirstByStr("202201"));
//		System.out.println(DateUtils.getMonthLastByStr("202201"));
//
//        List<String> monthList = Lists.newArrayList();
//        for(int i=0;i<=6;i++) {
//            String yearMonth = DateUtils.getPastMonth("202201", -i);
//            System.out.println(yearMonth);
//        }

//        Map<Date, Date> dateMap =  DateUtils.getApplyDateList(dateStr, nationCycle);
//        for(Date key:dateMap.keySet()) {
//            System.out.println(DateUtils.date2Str(key, DateUtils.date_sdf) + "=" + DateUtils.date2Str(dateMap.get(key), DateUtils.date_sdf));
//        }
//        System.out.println(DateUtils.getDaysOfMonth(dateStr));
//        System.out.println(DateUtils.getDaySub(dateStr, dateStrEnd));
//		System.out.println(DateUtils.date2Str(DateUtils.addDate(DateUtils.getDate(), -1), DateUtils.date_sdf));
//		System.out.println(DateUtils.dayCompare(dateStrEnd, DateUtils.getDate()));
//        System.out.println(DateUtils.date2Str(DateUtils.getPreDateCurMonth(dateStr, nationCycle), DateUtils.date_sdf));
    }
}