package yem.wmc.ydn.utils;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.exception.BosErrorCode;
import kd.bos.exception.KDException;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

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


/**
 * 日期工具类
 *@author 
 *@date 2019-09-13 下午8:20:16
 */
public class DateUtils {
	public static final String FORMAT_YMD = "yyyy-MM-dd";
    public static final String FORMAT_YMDHMS = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_yyyyMMdd = "yyyyMMdd";
    public static final DateTimeFormatter DATE_FORMATTER;
    public static final DateTimeFormatter DATETIME_FORMATTER;
    
    public static Date truncateDate(final Date dt) {
        if (dt == null) {
            return null;
        }
        final Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        cal.set(cal.get(1), cal.get(2), cal.get(5), 0, 0, 0);
        return new Date(cal.getTimeInMillis() / 1000L * 1000L);
    }
    
    public static Date getLastDay(final Date date, final int i) {
        final Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(5, cal.get(5) - i);
        return cal.getTime();
    }
    
    public static Date getNextDay(final Date date, final int i) {
        final Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(5, cal.get(5) + i);
        return cal.getTime();
    }
    
    public static int getDiffDays(final Date beginDate, final Date endDate) {
        if (beginDate == null || endDate == null) {
            throw new IllegalArgumentException("getDiffDays param is null!");
        }
        final long diff = (endDate.getTime() - beginDate.getTime()) / 86400000L;
        final int days = new Long(diff).intValue() + 1;
        return days;
    }
    
    public static Date getDataFormat(final Date date, final boolean isStart) {
        final String dateStr = new SimpleDateFormat("yyyy-MM-dd").format(date);
        String suffix = " 00:00:00";
        if (!isStart) {
            suffix = " 23:59:59";
        }
        try {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr + suffix);
        }
        catch (ParseException e) {
            throw new KDException((Throwable)e, BosErrorCode.systemError, new Object[0]);
        }
    }
    
    public static String formatString(final Date date, final String forPattern) {
        return new DateTime((Object)date).toString(DateTimeFormat.forPattern(forPattern));
    }
    
    public static int getDay(final Date date) {
        return Integer.parseInt(new DateTime((Object)date).toString(DateUtils.DATE_FORMATTER).substring(8));
    }
    
    public static int getMonth(final Date date) {
        return Integer.parseInt(new DateTime((Object)date).toString(DateUtils.DATE_FORMATTER).substring(5, 7));
    }
    
    public static int getYear(final Date date) {
        return Integer.parseInt(new DateTime((Object)date).toString(DateUtils.DATE_FORMATTER).substring(0, 4));
    }
    
    public static Map<String, Date> getWeekDate() {
        final Map<String, Date> weekDate = new HashMap<String, Date>();
        final Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int d = 0;
        if (cal.get(7) == 1) {
            d = -6;
        }
        else {
            d = 2 - cal.get(7);
        }
        cal.add(7, d);
        weekDate.put("beginDate", cal.getTime());
        cal.add(7, 6);
        weekDate.put("endDate", cal.getTime());
        return weekDate;
    }
    
    public static Date getMinMonthDate(Date date) {
        date = getDataFormat(date, true);
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(5, calendar.getActualMinimum(5));
        return calendar.getTime();
    }
    
    public static Date getMaxMonthDate(Date date) {
        date = getDataFormat(date, false);
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(5, calendar.getActualMaximum(5));
        return calendar.getTime();
    }
    
    public static boolean isSameDay(final Date date1, final Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        final Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        final Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return isSameDay(cal1, cal2);
    }
    
    public static boolean isSameDay(final Calendar cal1, final Calendar cal2) {
        return cal1 != null && cal2 != null && cal1.get(0) == cal2.get(0) && cal1.get(1) == cal2.get(1) && cal1.get(6) == cal2.get(6);
    }
    
    public static boolean isSameMonth(final Date d1, final Date d2) {
        return isSameDay(getMinMonthDate(d1), getMinMonthDate(d1));
    }
    
    public static void main(final String[] args) {
        System.out.println(new LocalDate().toString(DateUtils.DATE_FORMATTER));
        System.out.println(getDataFormat(new Date(), true));
        System.out.println(getDataFormat(new Date(), false));
        System.out.println(getNextDay(new Date(), -1));
    }
    
    /**
     * 获得当天0点时间
     *
     * @return
     */
    public static Date getTimesmorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
  
  
    }
    /**
     * 获得传入时间0点时间
     *
     * @return
     */
    public static Date getTimesmorning(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
  
  
    }
    /**
     * 获得昨天0点时间
     *
     * @return
     */
    public static Date getYesterdaymorning() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(getTimesmorning().getTime()-3600*24*1000);
        return cal.getTime();
    }
    // 获得当天近7天时间
    /**
     * 获得当天近7天时间
     *
     * @return
     */
    public static Date getWeekFromNow() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis( getTimesmorning().getTime()-3600*24*1000*7);
        return cal.getTime();
    }
  
    // 获得当天24点时间
    /**
     * 获得当天24点时间
     *
     * @return
     */
    public static Date getTimesnight() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 24);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    
    /**
     * 获得传入时间24点时间
     *
     * @return
     */
    public static Date getTimesnight(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 24);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
  
    // 获得本周一0点时间
    /**
     * 获得本周一0点时间
     *
     * @return
     */
    public static Date getTimesWeekmorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return cal.getTime();
    }
  
    // 获得本周日24点时间
    /**
     * 获得本周日24点时间
     *
     * @return
     */
    public static Date getTimesWeeknight() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getTimesWeekmorning());
        cal.add(Calendar.DAY_OF_WEEK, 7);
        return cal.getTime();
    }
  
    // 获得本月第一天0点时间
    /**
     * 获得本月第一天0点时间
     *
     * @return
     */
    public static Date getTimesMonthmorning() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        return cal.getTime();
    }
  
    // 获得本月最后一天24点时间
    /**
     * 获得本月最后一天24点时间
     *
     * @return
     */
    public static Date getTimesMonthnight() {
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 24);
        return cal.getTime();
    }
    
    /**
     * 获得下月第一天0点
     *
     * @return
     */
    public static Date getNextMonthnight() {
    	Calendar cal = Calendar.getInstance();
    	cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        cal.add(Calendar.MONTH, 1);
        return cal.getTime();
    }
    
    /**
     * 当前季度的结束时间，即2012-03-31 23:59:59
     *
     * @return
     */
    public static Date getCurrentQuarterEndTime() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getCurrentQuarterStartTime());
        cal.add(Calendar.MONTH, 3);
        return cal.getTime();
    }
    
    public static Date getCurrentQuarterStartTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3)
                c.set(Calendar.MONTH, 0);
            else if (currentMonth >= 4 && currentMonth <= 6)
                c.set(Calendar.MONTH, 3);
            else if (currentMonth >= 7 && currentMonth <= 9)
                c.set(Calendar.MONTH, 4);
            else if (currentMonth >= 10 && currentMonth <= 12)
                c.set(Calendar.MONTH, 9);
            c.set(Calendar.DATE, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }
    
    static {
        DATE_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
        DATETIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
    }
    
    /**
	 * 获取指定日期添加/减去指定天数后的日期
	 * 
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date addDays(Date date, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.clear();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, days);
		return calendar.getTime();
	}
	
	/**
	 * 日期格式化
	 * @param date
	 * @param format
	 * @return
	 */
	public static Date formatDate(String date, String format) {
		SimpleDateFormat dt = new SimpleDateFormat(format);
		try {
			return dt.parse(date);
		} catch (ParseException e) {
            e.printStackTrace();
		}
		return null;
	}

    /**
     * 日期格式化
     * @param date Feb 8, 2023 12:00:00 AM
     * @param format MMM dd, yyyy hh:mm:ss
     * @return data
     */
    public static Date formatDateLocale(String date, String format) {
        SimpleDateFormat dt = new SimpleDateFormat(format,Locale.CANADA);
        try {
            return dt.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    
	/**
	 * 日期格式化
	 * @param date
	 * @param format
	 * @return
	 */
	public static String getData(Date date, String format) {
		SimpleDateFormat dt = new SimpleDateFormat(format);
		return dt.format(date);
	}
	
	/**
	 * 日期格式化
	 * @param timeString ：Sun Mar 01 00:00:00 CST 2020
	 * @return yyyy-MM-dd
	 */
	public static String DateFormat(String timeString) {
		SimpleDateFormat sfEnd = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat sfStart = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH) ;
		try {
			String format = sfEnd.format(sfStart.parse(timeString));
			Date time = DateUtils.formatDate(format, "yyyy-MM-dd");
			timeString=DateUtils.formatString(time, DateUtils.FORMAT_YMD);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return timeString;
	}
	
	/***
	 * 得到两个时期相差天数
	 * @param one
	 * @param two
	 * @return
	 */
	 public static int getDistanceDays(Date one, Date two){  
	        int days=0;  
	        long time1 = one.getTime();  
			long time2 = two.getTime();  
			long diff ;  
			diff = time2 - time1;  
			days =  (int) (diff / (1000 * 60 * 60 * 24));  
	        return days;  
	 }
	 
    /**
     * 在原日期上加上一个天数
     *
     * @param dDate
     * @param iNbDay
     * @return
     */
    public static Date addDay(Date dDate, long iNbDay) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dDate);
        cal.add(Calendar.DAY_OF_MONTH, (int) iNbDay);
        Date result = cal.getTime();
        return result;
    }
    
    /**
     * 判断是否时期是否工作日
     *
     * @return
     */
    public static boolean isweekday(final Date dDate) {
		QFilter qFilter1 = new QFilter("tpv_holidaydate", QCP.equals, dDate);
		DynamicObject tpv_holiday = BusinessDataServiceHelper.loadSingle("tpv_holiday", "id,billno,tpv_holidaydate",
				new QFilter[] { qFilter1 });
		if (tpv_holiday != null) {
			return true;
		}else {
			return false;
		}
        
    }
    
    /**
     * 获得夺取当前日期 （前/后 n天的）的工作日;
     *
     * @return
     */
    public static Date getweekday(Date dDate, int addday ) {

    	int iNbDay = Math.abs(addday);
    	for(int days = 1 ; days <iNbDay+1 ; days++) {
    		Date weekdate = addDays(dDate,addday>=0?days:-days);
    		if(isweekday(weekdate)) {
    			iNbDay = iNbDay+1;
    		}
    	}
        	
    	return addDays(dDate,addday>=0?iNbDay:-iNbDay);
    }
    /**
     * 获取当年的第一天
     */
    public static Date getCurrentFirstOfYear(){
        Calendar currCal=Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getFirstOfYear(currentYear);
    }

    /**
     * 获取当年的最后一天
     */
    public static Date getCurrentLastOfYear() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getLastOfYear(currentYear);
    }
    /**
     * 获取某年第一天日期
     * @param year 年份
     * @return Date
     */
    public static Date getFirstOfYear(int year){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }



    /**
     * 获取某年最后一天日期
     * @param year 年份
     * @return Date
     */
    public static Date getLastOfYear(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTime();
    }

}
