package com.brilliance.isc.swift.objmtconvert.util;

import cn.hutool.core.lang.Assert;
import com.brilliance.swift.exception.SwiftException;
import com.brilliance.swift.util.NumberUtil;
import com.brilliance.swift.util.StringUtil;
import org.apache.commons.lang3.time.DateUtils;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil {

    public static String CURRENT_DATE = "";

    public static String defaultFormate = "yyyy-MM-dd HH:mm:ss,SSS"; // 默认的日期格式

    /***
     * @param paramDate
     *            日期
     * @param paramInt1
     *            0-6 毫秒、秒、分、时、日、月、年
     * @param paramInt2
     *            增量 为整型
     * ***/
    public static final Date dateAdd(Date paramDate, int paramInt1, int paramInt2) {
        if (paramDate == null)
            return null;
        Calendar localCalendar = Calendar.getInstance();
        localCalendar.setTime(paramDate);
        switch (paramInt1) {
            case 0:
                localCalendar.add(14, paramInt2);
                break;
            case 1:
                localCalendar.add(13, paramInt2);
                break;
            case 2:
                localCalendar.add(12, paramInt2);
                break;
            case 3:
                localCalendar.add(11, paramInt2);
                break;
            case 4:
                localCalendar.add(5, paramInt2);
                break;
            case 5:
                localCalendar.add(2, paramInt2);
                break;
            case 6:
                localCalendar.add(1, paramInt2);
        }
        return new Date(localCalendar.getTimeInMillis());
    }

    /**
     * 返回一个代表当期日期是星期几的数字。1表示星期天、2表示星期一、7表示星期六
     **/
    public static int getDayOfWeek(String year, String month, String day) {
        Calendar cal = new GregorianCalendar(new Integer(year).intValue(), new Integer(month).intValue() - 1, new Integer(day).intValue());
        return cal.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 当前时间是否符合时间表达式
     *
     * @param cron
     * @return
     * @throws ParseException
     */
    public static boolean isDateValid(String cron) throws ParseException {
        if (StringUtil.isEmpty(cron))
            return true;
        //CronExpression cronExpression = new CronExpression(cron);
        //	return cronExpression.isSatisfiedBy(new Date());
        return true;
    }

    /**
     * 默认格式格式化当前时间
     *
     * @return
     */
    public static String formatNow() {
        return DateUtil.formatNow(defaultFormate);
    }

    /**
     * 按指定格式格式化当前时间
     *
     * @return
     */
    public static String formatNow(String pattern) {
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(new Date());
    }

    /**
     * 默认格式格式化几分钟后的时间
     *
     * @param min
     * @return
     */
    public static String formatMinutesLater(int min) {
        Calendar c = Calendar.getInstance();
        Date date = new Date();
        c.setTime(date);
        c.add(Calendar.MINUTE, min);
        DateFormat dateFormat = new SimpleDateFormat(defaultFormate);
        return dateFormat.format(c.getTime());
    }

    /**
     * 按指定格式格式化几分钟后的时间
     *
     * @param min
     * @return
     */
    public static String formatMinutesLater(String pattern, int min) {
        Calendar c = Calendar.getInstance();
        Date date = new Date();
        c.setTime(date);
        c.set(Calendar.MINUTE, c.get(Calendar.MINUTE) + min);
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(c.getTime());
    }

    /**
     * 按默认格式格式化日期
     *
     * @param date
     * @return
     */
    public static String format(Date date) {
        return DateUtil.format(date, defaultFormate);
    }

    /**
     * 按指定格式格式化日期
     *
     * @param date
     * @return
     */
    public static String format(Date date, String pattern) {
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        if (date != null)
            return dateFormat.format(date);
        else
            return null;
    }

    /**
     * 格式化XML时间为字符串
     *
     * @param xgc
     * @param pattern
     * @return
     */
    public static String format(XMLGregorianCalendar xgc, String pattern) {
        Calendar calendar = xgc.toGregorianCalendar();
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        dateFormat.setTimeZone(calendar.getTimeZone());
        return dateFormat.format(calendar.getTime());
        /*Date date = xgc.toGregorianCalendar().getTime();
        return DateUtil.format(date, pattern);*/
    }

    /**
     * 指定格式的日期转化为XML时间
     *
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     * @throws DatatypeConfigurationException
     */
    public static XMLGregorianCalendar parseXMLGregorianCalendar(String time, String pattern) throws ParseException, DatatypeConfigurationException {
        return parseXMLGregorianCalendar(parseDate(time, pattern));
    }

    /**
     * Date转化为XMLGregorianCalendar
     *
     * @param date
     * @return
     * @throws ParseException
     * @throws DatatypeConfigurationException
     */
    public static XMLGregorianCalendar parseXMLGregorianCalendar(Date date) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        XMLGregorianCalendar xgc = null;
        try {
            xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
        } catch (DatatypeConfigurationException e) {

        }
        return xgc;
    }

    /**
     * 数据库Date类型转化为XML时间
     *
     * @param date
     * @return
     * @throws DatatypeConfigurationException
     */
    public XMLGregorianCalendar parseXMLGregorianCalendar(java.sql.Date date) throws DatatypeConfigurationException {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTimeInMillis(date.getTime());
        XMLGregorianCalendar xgc;
        xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
        return xgc;
    }

    /**
     * 将一个yyyy-MM-dd的时间字符串转化为XMLGregorianCalendar
     *
     * @param time
     * @return
     */
    public static XMLGregorianCalendar parseXMLGregorianCalendar(String time) {
        XMLGregorianCalendar xgc = null;
        try {
            xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar();
            Date date = DateUtil.parseDate(time.substring(0, 10), "yyyy-MM-dd");
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            xgc.setYear(c.get(Calendar.YEAR));
            xgc.setMonth(c.get(Calendar.MONTH) + 1);
            xgc.setDay(c.get(Calendar.DAY_OF_MONTH));
            xgc.setTimezone(new GregorianCalendar().getTimeZone().getOffset(System.currentTimeMillis()) / 1000 / 60);
        } catch (Exception e) {
            throw new SwiftException("00404", "parse date error.", e);
        }
        return xgc;
    }

    public static XMLGregorianCalendar parseXMLGregorianCalendar2(String time) {
        XMLGregorianCalendar xgc = null;
        try {
            xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar();
            Date date = DateUtil.parseDate(time.substring(0, 8), "yyyyMMdd");
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            xgc.setYear(c.get(Calendar.YEAR));
            xgc.setMonth(c.get(Calendar.MONTH) + 1);
            xgc.setDay(c.get(Calendar.DAY_OF_MONTH));
            xgc.setTimezone(new GregorianCalendar().getTimeZone().getOffset(System.currentTimeMillis()) / 1000 / 60);
        } catch (Exception e) {
            throw new SwiftException("00404", "parse date error.", e);
        }
        return xgc;
    }

    /**
     * XML时间转化为Date
     *
     * @param xgc
     * @return
     */
    public static Date parseDate(XMLGregorianCalendar xgc) {
        return xgc.toGregorianCalendar().getTime();
    }

    /**
     * 获取两个时间间隔几天
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static int getInterval(Date fromDate, Date toDate) {
        long interval = toDate.getTime() - fromDate.getTime();
        return (int) (interval / (24 * 3600000));
    }

    /**
     * 获取两个时间的分钟间隔
     *
     * @param fromDate
     * @param toDate
     * @return
     */
    public static double getIntervalMinutes(Date fromDate, Date toDate) {
        long interval = toDate.getTime() - fromDate.getTime();
        return NumberUtil.accurateDivide(interval, 60000, 2);
    }

    /**
     * 比较两个时间 如果相等，返回值为0 如果前一个时间比较早，返回值<0 如果前一个时间比较晚，返回值>0
     *
     * @param firstDate
     * @param secondDate
     * @return
     */
    public static int compareDate(Date firstDate, Date secondDate) {
        Calendar firstCalendar = new GregorianCalendar();
        firstCalendar.setTime(firstDate);

        Calendar secondCalendar = new GregorianCalendar();
        secondCalendar.setTime(secondDate);

        return firstCalendar.compareTo(secondCalendar);
    }

    /**
     * 字符串转化为Date类型
     *
     * @param date         日期字符串
     * @param parsePattern 日期格式
     * @return
     * @throws ParseException
     */
    public static Date parseDate(String date, String parsePattern) throws ParseException {
        return DateUtils.parseDate(date, new String[]{parsePattern});
    }

    /**
     * Date日期格式化之后再次转化为Date（可在需要改变Date携带的信息时使用，如希望把一个
     * 'yyyy-MM-dd'的日期变为只有年信息'yyyy'的日期）
     *
     * @param date
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static Date formatAndParseDate(Date date, String pattern) throws ParseException {
        String formatDate = DateUtil.format(date, pattern);
        return DateUtil.parseDate(formatDate, pattern);
    }

    /**
     * 日期字符串转化为其他日期信息的字符串
     *
     * @param date
     * @param parsePattern
     * @param formatPattern
     * @return
     * @throws ParseException
     */
    public static String parseAndFormatDate(String date, String parsePattern, String formatPattern) throws ParseException {
        Date parseDate = DateUtils.parseDate(date, new String[]{parsePattern});
        return DateUtil.format(parseDate, formatPattern);
    }

    /**
     * 判断两个日期是否在同一天
     *
     * @param preDate
     * @param currDate
     * @return
     * @throws ParseException
     */
    public static boolean checkSameDay(Date preDate, Date currDate) throws ParseException {
        if (preDate != null) {
            currDate = DateUtil.clearTime(currDate);
            preDate = DateUtil.clearTime(preDate);
            if (DateUtil.compareDate(preDate, currDate) == 0)
                return true;
        }
        return false;
    }

    /**
     * 去掉日期中的天、分、秒、毫秒信息
     *
     * @param date
     * @return
     */
    private static Date clearTime(Date date) {
        // 也可以parseandformat的方法实现
        Calendar calendar = new GregorianCalendar();
        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);
        date = calendar.getTime();
        return date;
    }

    public static Date parseDate(Date date, String parsePattern) throws ParseException {
        String dateStr = DateUtil.parseAndFormatDate(DateUtil.format(date), DateUtil.defaultFormate, parsePattern);
        Date newDate = DateUtil.parseDate(dateStr, parsePattern);
        return newDate;
    }

    /**
     * 获取当前日期
     */
    public static Timestamp getTimestamp() {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = null;
        try {

            d = sf.parse("2010-05-14 00:00:00");
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Assert.notNull(d);
        Timestamp timestamp = new Timestamp(d.getTime());
        return timestamp;

        /*
         * Date dNow = new Date(); // 当前时间 Date dBefore = new Date(); Calendar
         * calendar = Calendar.getInstance(); // 得到日历 calendar.setTime(dNow);//
         * 把当前时间赋给日历 // calendar.add(Calendar.DAY_OF_MONTH, -1); // 设置为前一天
         * dBefore = calendar.getTime(); // 得到当前天的时间 Timestamp timestamp = new
         * Timestamp(dBefore.getTime()); return timestamp;
         */
    }

    public static final Timestamp time2(String paramString1, String paramString2) throws ParseException {

        return new Timestamp(new SimpleDateFormat(paramString2).parse(paramString1).getTime());
    }

    // 根据当前日期获取前一天日期
    public static String getLastDay(String str, String pattern) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        Date date = df.parse(str);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        date = calendar.getTime();
        return DateUtil.format(date, pattern);
    }

}
