package cn.com.countrygarden.bi.main.util;

import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class DateUtil {

    public static String simpleFormat(Date date) {
        return new SimpleDateFormat("yyyy-MM-dd").format(date);
    }
    public static String simpleFormat(Date date, String format) {
        return new SimpleDateFormat(format).format(date);
    }
    public static String simpleFormat1(Date date) {
        return new SimpleDateFormat("yyyyMMdd").format(date);
    }
    public static String simpleFormatAccurate(Date date) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }

    public static Date parseDate(String dateString) {
        Date date;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(dateString);
        } catch (ParseException e) {
            date = null;
        }
        return date;
    }


    public static Date parseDateWuyexie(String dateString) {
        Date date;
        try {
            date = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(dateString);
        } catch (ParseException e) {
            date = null;
        }
        return date;
    }

    public static Date parseDateTime(String dateString) {
        Date date;
        try {
            date = new SimpleDateFormat("yyyy/MM/dd HH:mm").parse(dateString);
        } catch (ParseException e) {
            date = null;
        }
        return date;
    }

    public static Date parseDate(String dateString, String format) {
        Date date;
        try {
            date = new SimpleDateFormat(format).parse(dateString);
        } catch (ParseException e) {
            date = null;
        }
        return date;
    }
    public static String getFirstDayOfThisYear() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-01-01");
        return dateFormat.format(new Date());
    }


    public static String getMonday(int interval) {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);//将每周第一天设为星期一，默认是星期天
        cal.add(Calendar.DATE, -interval * 7);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
    }

    public static String getSunday(int interval) {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);//将每周第一天设为星期一，默认是星期天
        cal.add(Calendar.DATE, -interval * 7);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
    }

    public static String getFirstDayOfMonth() {
        String firstDayofMonth;
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        firstDayofMonth = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
        return firstDayofMonth + " 00:00:00";
    }

    public static String getLastDayOfMonth() {
        String lastDayofMonth;
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        lastDayofMonth = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
        return lastDayofMonth + " 23:59:59";
    }

    public static String getFirstDayOfPreviousMonth() {
        String firstDayofMonth;
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        firstDayofMonth = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
        return firstDayofMonth + " 00:00:00";
    }

    public static String getLastDayOfPreviousMonth() {
        String lastDayofMonth;
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        lastDayofMonth = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
        return lastDayofMonth + " 23:59:59";
    }

    public static String getStartOfYesterday() {
        String yesterdayStrig = "";
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime yesterday = localDateTime.minusDays(1);
        try {
            DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
            yesterdayStrig = yesterday.format(format);
        } catch (DateTimeException e) {

        }

        return yesterdayStrig;
    }

    public static String getEndOfYesterday() {
        String yesterdayStrig = "";
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDateTime yesterday = localDateTime.minusDays(1);
        try {
            DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59");
            yesterdayStrig = yesterday.format(format);
        } catch (DateTimeException e) {

        }

        return yesterdayStrig;
    }

    public static String getStartOfToday() {
        String yesterdayStrig = "";
        LocalDateTime localDateTime = LocalDateTime.now();
        try {
            DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00");
            yesterdayStrig = localDateTime.format(format);
        } catch (DateTimeException e) {

        }

        return yesterdayStrig;
    }

    public static  Calendar removeTime(Calendar calendar){
        calendar.set(Calendar.HOUR,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);
        return calendar;
    }

    public static Calendar goToLastWeek(Calendar calendar){
        calendar.add(Calendar.DATE,-7);
        return calendar;
    }

    public static Calendar goToFirstDateOfWeek(Calendar calendar,boolean isStartOfSunDay){
        boolean isSunDay = false;
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

        if(isStartOfSunDay && isSunDay){
            if(dayOfWeek==1){
                return calendar;
            }

            calendar.add(Calendar.DATE,1-dayOfWeek);
        } else{
            if(dayOfWeek == 2){
                return calendar;
            }
            calendar.add(Calendar.DATE,2-dayOfWeek);
        }
        return calendar;
    }

    public static Calendar goToLastDateOfWeek(Calendar calendar,boolean isStartOfSunDay){
        boolean isSunDay = false;
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

        if(isStartOfSunDay && isSunDay){
            if(dayOfWeek==7){
                return calendar;
            }

            calendar.add(Calendar.DATE,6-dayOfWeek);
        } else{
            if(dayOfWeek == 1){
                return calendar;
            }
            calendar.add(Calendar.DATE,7-dayOfWeek);
        }
        return calendar;
    }

    public static String getEndOfToday() {
        String yesterdayStrig = "";
        LocalDateTime localDateTime = LocalDateTime.now();
        try {
            DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59");
            yesterdayStrig = localDateTime.format(format);
        } catch (DateTimeException e) {

        }

        return yesterdayStrig;
    }


    public static String weekFormat(Date startDate, Date endDate) {
        /*
         2017第28周(7.3-7.9)
         */
        SimpleDateFormat weekformatter = new SimpleDateFormat("yyyy第w周");
        SimpleDateFormat dateFormat = new SimpleDateFormat("M.d");
        String weekString = weekformatter.format(startDate);
        String startDateStr = dateFormat.format(startDate);
        String endDateStr = dateFormat.format(endDate);
        return String.format("%s(%s-%s)", weekString, startDateStr, endDateStr);
    }
    public static String monthFormat(Date startDate,Date endDate) {
        SimpleDateFormat monthformatter = new SimpleDateFormat("yyyy第M月");
        SimpleDateFormat dateFormat = new SimpleDateFormat("M.d");
        String monthStr = monthformatter.format(startDate);
        String startDateStr = dateFormat.format(startDate);
        String endDateStr = dateFormat.format(endDate);
        return String.format("%s(%s-%s)", monthStr, startDateStr, endDateStr);
    }

    public int getCurrentQuater(){
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH);
        if(0<=month & month<=2){
            return  1;
        }
        if(3<=month & month<=5){
            return  2;
        }
        if(6<=month & month<=8){
            return  3;
        }
        return 4;
    }

    public static int getQuater(Calendar calendar){
        int month = calendar.get(Calendar.MONTH);
        if(month>=0 && month<=2){
            return 1;
        }
        if(month>=3 && month<=5){
            return 2;
        }
        if(month>=6 && month<=8){
            return 3;
        } else {
            return 4;
        }
    }

    public static Date[] getQuarterTime(int year, int quarter) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.YEAR, year);
        Date startDate = null;
        Date endDate = null;
        switch (quarter) {
            case 1:
                calendar.set(Calendar.MONTH, 0);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                startDate = calendar.getTime();
                calendar.set(Calendar.MONTH, 3);
                calendar.add(Calendar.DATE, -1);
                endDate = calendar.getTime();
                break;
            case 2:
                calendar.set(Calendar.MONTH, 3);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                startDate = calendar.getTime();
                calendar.set(Calendar.MONTH, 6);
                calendar.add(Calendar.DATE, -1);
                endDate = calendar.getTime();
                break;
            case 3:
                calendar.set(Calendar.MONTH, 6);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                startDate = calendar.getTime();
                calendar.set(Calendar.MONTH, 9);
                calendar.add(Calendar.DATE, -1);
                endDate = calendar.getTime();
                break;
            case 4:
                calendar.set(Calendar.MONTH, 9);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                startDate = calendar.getTime();
                calendar.set(Calendar.MONTH, 11);
                int day = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                calendar.set(Calendar.DAY_OF_MONTH, day);
                endDate = calendar.getTime();
                break;
        }
        Date[] result = {startDate, endDate};

        return result;
    }


    public static Date[] convertWeekRange(String startDateStr, String endDateStr) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date startDate = format.parse(startDateStr);
            Date endDate = format.parse(endDateStr);
            Iterator<Calendar> iterator = DateUtils.iterator(startDate, DateUtils.RANGE_WEEK_MONDAY);
            Calendar firstMonDay = iterator.next();
            iterator = DateUtils.iterator(endDate, DateUtils.RANGE_WEEK_MONDAY);
            Calendar lastSunDay = iterator.next();
            lastSunDay.add(Calendar.DAY_OF_YEAR, 6);
            List<Date> dateRange = new ArrayList<Date>();
            dateRange.add(firstMonDay.getTime());

            firstMonDay.add(Calendar.DAY_OF_YEAR, 6);
            dateRange.add(firstMonDay.getTime());
            long lastTime = lastSunDay.getTimeInMillis();
            long sunDayTime = firstMonDay.getTimeInMillis();
            while (lastTime > sunDayTime) {
                firstMonDay.add(Calendar.DAY_OF_YEAR, 1);
                dateRange.add(firstMonDay.getTime());
                firstMonDay.add(Calendar.DAY_OF_YEAR, 6);
                dateRange.add(firstMonDay.getTime());
                sunDayTime = firstMonDay.getTimeInMillis();
            }
            return dateRange.toArray(new Date[]{});

        } catch (Exception exception) {

        }

        return null;
    }

    public static int getYear() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.YEAR);
    }

    public static int getWeekOfYear() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 取得当前日期所在周的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.SUNDAY);
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK,
                calendar.getFirstDayOfWeek()); // Sunday
        return calendar.getTime();
    }

    /**
     * 得到某年某周的第一天
     *
     * @param year
     * @param week
     * @return
     */
    public static Date getFirstDayOfWeek(int year, int week) {

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.WEEK_OF_YEAR,week);
        removeTime(calendar);

        return getFirstDayOfWeek(calendar.getTime());
    }

    /**
     * 取得当前日期所在周的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK,
                calendar.getFirstDayOfWeek() + 6);
        return calendar.getTime();
    }

    /**
     * 得到某年某周的最后一天
     *
     * @param year
     * @param week
     * @return
     */
    public static Date getLastDayOfWeek(int year, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.WEEK_OF_YEAR,week);
        removeTime(calendar);

        return getLastDayOfWeek(calendar.getTime());
    }

    public static Date[] getMonthRang(Date startDate,Date endDate){
        List<Date> dateList = new ArrayList<Date>(10);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        dateList.add(calendar.getTime());
        int endDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH,endDay);
        dateList.add(calendar.getTime());
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);
        endDay = endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        endCalendar.set(Calendar.DAY_OF_MONTH,endDay);

        while(calendar.compareTo(endCalendar)<0){
            calendar.add(Calendar.MONTH,1);
            calendar.set(Calendar.DAY_OF_MONTH,1);
            dateList.add(calendar.getTime());
            endDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            calendar.set(Calendar.DAY_OF_MONTH,endDay);
            dateList.add(calendar.getTime());
        }
        return dateList.toArray(new Date[]{});
    }

    public static Date[] getQuarterRang(Date startDate,Date endDate){
        List<Date> dateList = new ArrayList<Date>(10);
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(startDate);
        int startYear = startCalendar.get(Calendar.YEAR);
        int startQuater = DateUtil.getQuater(startCalendar);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);
        int endYear = endCalendar.get(Calendar.YEAR);
        int endQuater = DateUtil.getQuater(endCalendar);
        Date[] rang = DateUtil.getQuarterTime(startYear,startQuater);
        dateList.add(rang[0]);
        dateList.add(rang[1]);
        startCalendar.add(Calendar.MONTH,3);
        startYear = startCalendar.get(Calendar.YEAR);
        startQuater = DateUtil.getQuater(startCalendar);
        while((startYear*10+ startQuater)<(endYear*10+endQuater) ){
            rang = DateUtil.getQuarterTime(startYear,startQuater);
            dateList.add(rang[0]);
            dateList.add(rang[1]);
            startCalendar.add(Calendar.MONTH,3);
            startYear = startCalendar.get(Calendar.YEAR);
            startQuater = DateUtil.getQuater(startCalendar);
        }
        return dateList.toArray(new Date[]{});
    }

    public static void main(String[] args) {
//        Date[] dates = convertWeekRange("2017-09-10", "2017-09-13");
//        for (Date d : dates) {
//            System.out.println(d);
//        }
//        DecimalFormat df = new DecimalFormat("0.##");
//        System.out.println(df.format(new BigDecimal("1")));
//        System.out.println(df.format(new BigDecimal("1.0")));
//        System.out.println(df.format(new BigDecimal("1.12333")));
//
//        System.out.println("getFirstDayOfWeek：" + DateUtil.getFirstDayOfWeek(2017, 38));
//        System.out.println("getLastDayOfWeek：" + DateUtil.getLastDayOfWeek(2017, 38));

//        System.out.println( DateUtil.getFirstDayOfWeek(2017,37));
//        System.out.println( DateUtil.getLastDayOfWeek(2017,37));
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH");
        Date[] rang = DateUtil.getMonthRang(DateUtil.parseDate("2017-01-01"),DateUtil.parseDate("2017-11-01"));
        for(int i=0;i<rang.length;i=i+2){
            System.out.println(format.format(rang[i])+":"+format.format(rang[i+1]));
        }
    }

    /**
     * 计算相差多少天
     * @param startDate
     * @param endDate
     * @return
     */
    public static int diffDay(Date startDate,  Date endDate){
        long nd = 1000 * 24 * 60 * 60;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - startDate.getTime();
        // 计算差多少天
        int day = (int)(diff / nd);
        return day;
    }

    public static String dateToStrOfFormat(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String dateStr;
        try {
            dateStr = sdf.format(date);
        } catch (Exception e) {
            throw new RuntimeException("日期格式转换异常！");
        }
        return dateStr;
    }

    /**
     * 判断选择的日期是否是本月
     * @param time
     * @return
     */
    public static boolean isThisMonth(Date time) {
        return isThisTime(time,"yyyy-MM");
    }

    public static boolean isLastMonth(Date time) {
        Calendar instance = Calendar.getInstance();
        instance.setTime(time);
        instance.set(Calendar.MONTH,instance.get(Calendar.MONTH)+1);
        return isThisTime(instance.getTime(),"yyyy-MM");
    }


    private static boolean isThisTime(Date date,String pattern) {
        String param = DateFormatUtils.format(date, pattern);
        String now = DateFormatUtils.format(new Date(), pattern);
        if(param.equals(now)){
            return true;
        }
        return false;
    }

    /**
     * 判断时间格式 格式必须为“YYYY-MM-dd”
     * @param sDate
     * @return
     */
    public static boolean isLegalDate(String sDate) {
        int legalLen = 10;
        if ((sDate == null) || (sDate.length() != legalLen)) {
            return false;
        }

        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = formatter.parse(sDate);
            return sDate.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取某年某月开始日期
     * @return String
     * **/
    public static String getMonthStart(int year,int month){
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month-1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 00:00:00";
    }

    /**
     * 获取某年某月最后一天
     * @return String
     * **/
    public static String getMonthEnd(int year,int month){
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month-1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time)+" 23:59:59";
    }

    /**
     * 获取昨天
     * @return String
     * */
    public static String getYestoday(){
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy-MM-dd").format(time);
    }

    /**
     * 获取昨天
     * @return String
     * */
    public static String getYestodaytijis(){
        Calendar cal=Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        Date time=cal.getTime();
        return new SimpleDateFormat("yyyy/MM/dd").format(time);
    }

    // 获取上一个月
    public static String Shangyue(){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月
        date = calendar.getTime();
        String accDate = format.format(date);
        return accDate;
    }
}