package com.house365.web.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 日期时间工具类
 *
 * @author huaqingchun * @version 1.0
 * @date
 */
public class DateTimeUtils {

    public static final String DEFAULT_DATE_FORMAT_PATTERN_SHORT = "yyyy-MM-dd";

    public static final String DEFAULT_DATE_FORMAT_PATTERN_FULL = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_FORMAT_PATTERN_TIGHT = "yyyyMMddHHmmssSSS";
    /**
     * 一天的秒数
     */
    public static int ONE_DAY_SECONDS = 24 * 60 * 60;
    /**
     * 一年 365 天的秒数
     */
    public static int ONE_YEAR_SECONDS = ONE_DAY_SECONDS * 365;
    /**
     * 十年 365 天的秒数
     */
    public static int TEN_YEAR_SECONDS = ONE_YEAR_SECONDS * 10;
    /**
     * 日期格式为yyyy-MM-dd HH:mm
     */
    private static SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.CHINA);
    /**
     * 日期格式为yyyy-MM-dd
     */
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
    private static Map<String, SimpleDateFormat> dateFormatCache = new ConcurrentHashMap<String, SimpleDateFormat>();

    /**
     * 以yyyy-MM-dd HH:mm:ss形式返回当前时间的字符串
     *
     * @return
     */
    public static String getCurrentDateTimeString() {
        return getCurrentDateString(DEFAULT_DATE_FORMAT_PATTERN_FULL);
    }

    /**
     * 以yyyy-MM-dd形式返回当前日期的字符串
     *
     * @return
     */
    public static String getCurrentDateString() {
        return getCurrentDateString(DEFAULT_DATE_FORMAT_PATTERN_SHORT);
    }

    /**
     * 返回pattern所指定的当前时间的字符串
     *
     * @param pattern
     * @return
     */
    public static String getCurrentDateString(String pattern) {
        if (pattern == null || "".equals(pattern.trim())) {
            return null;
        }
        SimpleDateFormat sdf = null;
        try {
            sdf = new SimpleDateFormat(pattern);
        } catch (Exception e) {
            e.printStackTrace();
            sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT_PATTERN_FULL);
        }
        return sdf.format(new Date());
    }

    /**
     * 返回时间date所指定的日期格式的字符串形式
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String getDateString(Date date, String pattern) {
        if (date == null || pattern == null || "".equals(pattern.trim())) {
            return null;
        }
        SimpleDateFormat sdf = null;
        if (dateFormatCache.containsKey(pattern)) {
            sdf = dateFormatCache.get(pattern);
        } else {
            try {
                sdf = new SimpleDateFormat(pattern);
                dateFormatCache.put(pattern, sdf);
            } catch (Exception e) {
                e.printStackTrace();
                sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT_PATTERN_FULL);
            }
        }
        return sdf.format(date);
    }

    /**
     * 将dateTimeString按照格式pattern转换成Date
     *
     * @param dateTimeString
     * @param pattern
     * @return
     */
    public static Date getDateByString(String dateTimeString, String pattern) {
        if (dateTimeString == null || "".equals(dateTimeString.trim()) || pattern == null || "".equals(pattern.trim())) {
            return null;
        }
        SimpleDateFormat sdf = null;
        if (dateFormatCache.containsKey(pattern)) {
            sdf = dateFormatCache.get(pattern);
        } else {
            sdf = new SimpleDateFormat(pattern);
            dateFormatCache.put(pattern, sdf);
        }
        try {
            return sdf.parse(dateTimeString);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将dateTimeString按照默认格式yyyy-MM-dd HH:mm:ss转换成Date
     *
     * @param dateTimeString
     * @return
     */
    public static Date getDateByString(String dateTimeString) {
        return getDateByString(dateTimeString, DEFAULT_DATE_FORMAT_PATTERN_FULL);
    }

    /**
     * 时间加减方法,根据type类型，加减value
     *
     * @param date
     * @param type  操作对象，年/月/日/时/分/秒，eg：Calendar.MONTH
     * @param value 更新值
     * @return
     */
    public static Date getUpdateDateTime(Date date, Integer type, Integer value) {
        if (null == date || null == value || null == type) {
            return null;
        }
        try {
            Calendar calendar = Calendar.getInstance();// 日历对象
            calendar.setTime(date);// 设置当前日期
            calendar.add(type, value);// 时间更改
            return calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 日期转化为大写
     *
     * @param date
     * @return
     */
    public static String dataToUpper(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        int year = ca.get(Calendar.YEAR);
        int month = ca.get(Calendar.MONTH) + 1;
        int day = ca.get(Calendar.DAY_OF_MONTH);
        return numToUpper(year) + "年" + monthToUppder(month) + "月" + dayToUppder(day) + "日";
    }

    /**
     * 将数字转化为大写
     *
     * @param num
     * @return
     */
    public static String numToUpper(int num) {
        // String u[] = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
        // String u[] = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        String u[] = {"〇", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        char[] str = String.valueOf(num).toCharArray();
        String rstr = "";
        for (int i = 0; i < str.length; i++) {
            rstr = rstr + u[Integer.parseInt(str[i] + "")];
        }
        return rstr;
    }

    /**
     * 月转化为大写 〈功能详细描述〉
     *
     * @param month
     * @return
     */
    public static String monthToUppder(int month) {
        if (month < 10) {
            return numToUpper(month);
        } else if (month == 10) {
            return "十";
        } else {
            return "十" + numToUpper(month - 10);
        }
    }

    /**
     * 日转化为大写
     *
     * @param day
     * @return
     */
    public static String dayToUppder(int day) {
        if (day < 20) {
            return monthToUppder(day);
        } else {
            char[] str = String.valueOf(day).toCharArray();
            if (str[1] == '0') {
                return numToUpper(Integer.parseInt(str[0] + "")) + "十";
            } else {
                return numToUpper(Integer.parseInt(str[0] + "")) + "十" + numToUpper(Integer.parseInt(str[1] + ""));
            }
        }
    }

    public static Date getSomeDate(int i) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, i);
        return c.getTime();
    }

    /**
     * 功能描述: <br>
     * 根据指定格式对当前日期进行格式化
     * (传入：String，返回：String)
     *
     * @param date   date 传入日期类型日期
     * @param format format 需要转化的格式
     * @return String 转换后的字符串格式日期
     */
    public static String parseDate(Date date, String format) {
        SimpleDateFormat dateformat = new SimpleDateFormat(format);
        return dateformat.format(date);
    }

    /**
     * 功能描述: <br>
     * 根据指定格式对当前日期进行格式化
     * (传入：String，返回：Date)
     *
     * @param datestr 传入字符串类型日期
     * @param dateFormate 需要转化的格式
     * @return Date 转换后的日期类型日期
     */
    public static Date parseDate(String datestr, String dateFormate) {
        SimpleDateFormat df = new SimpleDateFormat(dateFormate);
        Date date = null;
        try {
            date = df.parse(datestr);
        } catch (java.text.ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 取得指定日期所在月的第一天
     *
     * @param date , date
     * @return java.sql.Timestamp instance
     * @since 1.0
     */
    public static Date getFirstDayOfMonth(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.add(Calendar.DATE, 1 - day);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date getFirstDayOfWeek(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        int curDay = calendar.get(Calendar.DAY_OF_WEEK);
        if (curDay == 1) {
            calendar.add(Calendar.DATE, -6);
        } else {
            calendar.add(Calendar.DATE, 2 - curDay);
        }
        return calendar.getTime();
    }

    public static Date getToday(Date date){
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date getDaysAgo(Date date,int day){
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DATE, -day);
        return calendar.getTime();
    }

    public static Date getDaysAfter(Date date,int day){
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    public static Date getTimeAfterDays(Date date,int day){
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

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

    public static Date getYearsAgo(Date date,int year){
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.YEAR, -year);
        return calendar.getTime();
    }

    /**
     * 当前季度的开始时间
     */
    public static Date getCurrentQuarterStartTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        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, 6);
            else if (currentMonth >= 10 && currentMonth <= 12)
                c.set(Calendar.MONTH, 9);
            c.set(Calendar.DATE, 1);
            now = datetimeFormat.parse(dateFormat.format(c.getTime()) + " 00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    public static long getDatePoor(Date endDate, Date nowDate) {

        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh + day * 24;
        // 计算差多少分钟
        long min = diff % nd % nh / nm + day * 24 * 60;
        return min;
    }

    /**
     * 当前季度的结束时间
     */
    public static Date getCurrentQuarterEndTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 2);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 8);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = datetimeFormat.parse(dateFormat.format(c.getTime()) + " 23:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    public static void main(String[] args) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        getDatePoor(sdf.parse("2019-11-06 10:01:35"), sdf.parse("2019-11-06 10:05:33"));

//        System.out.println(DateTimeUtils.dataToUpper(new Date()));
//        System.out.println(getFirstDayOfWeek(new Date()));
//        Date test = parseDate("2018-04","yy-MM");
//        System.out.println(DateTimeUtils.parseDate(getMonthAgo(new Date(),1),"yy-MM"));
    }
}
