package com.infoepoch.pms.dispatchassistant.common.utils;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateTool {

    // 毫秒换成秒
    public final static BigDecimal MILLISECOND_TO_SECOND = new BigDecimal("1000");
    // 秒转换成分钟
    public final static BigDecimal SECOND_TO_MINUTE = new BigDecimal("60");
    // 分钟转换成小时
    public final static BigDecimal MINUTE_TO_HOUR = new BigDecimal("60");
    // 小时转换成天
    public final static BigDecimal HOUR_TO_DAY = new BigDecimal("24");
    // 天转换成周
    public final static BigDecimal DAY_TO_WEEK = new BigDecimal("7");

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

    public final static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public final static String YYYYMMDD = "yyyyMMdd";

    /**
     * 毫秒转换成周
     *
     * @param millisecond
     * @return
     */
    public static BigDecimal millisecondToWeek(long millisecond) {
        BigDecimal millisecondDecimal = new BigDecimal(String.valueOf(millisecond));
        return millisecondDecimal.divide(MILLISECOND_TO_SECOND, 10, BigDecimal.ROUND_HALF_UP)
                .divide(SECOND_TO_MINUTE, 10, BigDecimal.ROUND_HALF_UP)
                .divide(MINUTE_TO_HOUR, 10, BigDecimal.ROUND_HALF_UP)
                .divide(HOUR_TO_DAY, 10, BigDecimal.ROUND_HALF_UP)
                .divide(DAY_TO_WEEK, 10, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 毫秒转换成天
     *
     * @param millisecond
     * @return
     */
    public static BigDecimal millisecondToDay(long millisecond) {
        BigDecimal millisecondDecimal = new BigDecimal(String.valueOf(millisecond));
        return millisecondDecimal.divide(MILLISECOND_TO_SECOND, 10, BigDecimal.ROUND_HALF_UP)
                .divide(SECOND_TO_MINUTE, 10, BigDecimal.ROUND_HALF_UP)
                .divide(MINUTE_TO_HOUR, 10, BigDecimal.ROUND_HALF_UP)
                .divide(HOUR_TO_DAY, 10, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 毫秒转换成小时
     *
     * @param millisecond
     * @return
     */
    public static BigDecimal millisecondToHour(long millisecond) {
        BigDecimal millisecondDecimal = new BigDecimal(String.valueOf(millisecond));
        return millisecondDecimal.divide(MILLISECOND_TO_SECOND, 10, BigDecimal.ROUND_HALF_UP)
                .divide(SECOND_TO_MINUTE, 10, BigDecimal.ROUND_HALF_UP)
                .divide(MINUTE_TO_HOUR, 10, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 毫秒转换成分钟
     *
     * @param millisecond
     * @return
     */
    public static BigDecimal millisecondToMinute(long millisecond) {
        BigDecimal millisecondDecimal = new BigDecimal(String.valueOf(millisecond));
        return millisecondDecimal.divide(MILLISECOND_TO_SECOND, 10, BigDecimal.ROUND_HALF_UP)
                .divide(SECOND_TO_MINUTE, 10, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 毫秒转换成秒
     *
     * @param millisecond
     * @return
     */
    public static BigDecimal millisecondToSecond(long millisecond) {
        BigDecimal millisecondDecimal = new BigDecimal(String.valueOf(millisecond));
        return millisecondDecimal.divide(MILLISECOND_TO_SECOND, 10, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * @param dateStr
     * @return
     */
    public static Date getDate(String dateStr) {
        Date date = getDate(dateStr, YYYY_MM_DD_HH_MM_SS);
        if (date == null)
            date = getDate(dateStr, YYYY_MM_DD);
        return date;
    }

    /**
     * @param dateStr
     * @param format
     * @return
     */
    public static Date getDate(String dateStr, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(dateStr);
        } catch (ParseException | NullPointerException e) {
            return null;
        }
    }

    /**
     * 格式化日期
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return format(date, YYYY_MM_DD);
    }

    /**
     * 格式化时间
     *
     * @param date
     * @param format
     * @return
     */
    public static String format(Date date, String format) {
        try {
            if(date==null)
                return null;
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取指定周的第一天
     *
     * @param date
     * @param deviation
     * @return
     */
    public static Date getFirstDayOfWeek(Date date, int deviation) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.WEEK_OF_YEAR, deviation);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定周的最后一天
     *
     * @param date
     * @param deviation
     * @return
     */
    public static Date getLastDayOfWeek(Date date, int deviation) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.WEEK_OF_YEAR, deviation + 1);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取指定月的最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static Date getLastDayOfMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        return calendar.getTime();
    }

    /**
     * 获取月份的第几周
     *
     * @param date
     * @return
     */
    public static int getWeekIndexOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int weekIndex = calendar.get(Calendar.WEEK_OF_MONTH);
        if (Calendar.SUNDAY == calendar.get(Calendar.DAY_OF_WEEK)) {
            if (calendar.get(Calendar.DAY_OF_MONTH) > 1) {
                weekIndex = weekIndex - 1;
            }
        }
        return weekIndex;
    }

    /**
     * 获取当前周的第一天
     *
     * @param date
     * @return
     */
    public static Date getWeekFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 如果是周日，那么取上一周的周一（系统中认为周日是一周的第一天）
        if (Calendar.SUNDAY == calendar.get(Calendar.DAY_OF_WEEK)) {
            calendar.add(Calendar.WEEK_OF_YEAR, -1);
        }
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return calendar.getTime();
    }

    /**
     *
     * @param year
     * @param month
     * @param week
     * @return
     */
    public static Date getWeekFirstDay(int year, int month, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.WEEK_OF_MONTH, week);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return calendar.getTime();
    }

    /**
     * 获取当前周的最后一天
     *
     * @param date
     * @return
     */
    public static Date getWeekLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 如果不是周日，那么取下一周的周日时间为周最后一天（系统中认为周日是一周的第一天）
        if (Calendar.SUNDAY != calendar.get(Calendar.DAY_OF_WEEK)) {
            calendar.add(Calendar.WEEK_OF_YEAR, 1);
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        }
        return calendar.getTime();
    }

    /**
     *
     * @param year
     * @param month
     * @param week
     * @return
     */
    public static Date getWeekLastDay(int year, int month, int week) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.WEEK_OF_MONTH, week);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        calendar.add(Calendar.WEEK_OF_YEAR, 1);
        return calendar.getTime();
    }


    /**
     * 获取周的第几天
     *
     * @param date
     * @return
     */
    public static int getDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 获取月份
     *
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取年份
     *
     * @param date
     * @return
     */
    public static int getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 返回传入的时间增加天数后的时间
     * @param date
     * @param day
     * @return
     */
    public static Date getDateAddDay(Date date,int day) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 将Date类转换为XMLGregorianCalendar
     *
     * @param date
     * @return
     */
    public static XMLGregorianCalendar dateToXmlDate(Date date) {
        if (date != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            DatatypeFactory dtf = null;
            try {
                dtf = DatatypeFactory.newInstance();
            } catch (DatatypeConfigurationException e) {
            }
            XMLGregorianCalendar dateType = dtf.newXMLGregorianCalendar();
            dateType.setYear(cal.get(Calendar.YEAR));
            //由于Calendar.MONTH取值范围为0~11,需要加1
            dateType.setMonth(cal.get(Calendar.MONTH) + 1);
            dateType.setDay(cal.get(Calendar.DAY_OF_MONTH));
            dateType.setHour(cal.get(Calendar.HOUR_OF_DAY));
            dateType.setMinute(cal.get(Calendar.MINUTE));
            dateType.setSecond(cal.get(Calendar.SECOND));
            return dateType;
        }
        return null;
    }

}
