package com.esv.freight.file.common.util;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.Date;

/**
 * @description: 日期工具类
 * @project: SpringCloudTemplate
 * @name: com.esv.springcloud.template.common.util.DateUtils
 * @author: 黄朝斌
 * @email: huangchaobin@esvtek.com
 * @createTime: 2020/03/12 18:02
 * @version:1.0
 */
public class DateUtils {

    public static final String DATE_FORMAT0 = "yyyy-MM-dd HH:mm:ss:SSS";
    public static final String DATE_FORMAT1 = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT2 = "yyyyMMdd";
    public static final String DATE_FORMAT3 = "yyyy-MM-dd";
    public static final String DATE_FORMAT4 = "yyyyMMddHHmmss";
    public static final String DATE_FORMAT5 = "yyyy-MM";
    public static final String DATE_FORMAT6 = "yyyyMMddHHmmssSSS";
    public static final String DATE_FORMAT7 = "MMdd";
    public static final String DATE_FORMAT8 = "mm HH";
    public static final String DATE_FORMAT9 = "HH:mm:ss";

    /**
     * 一个月的时间换算成秒：30 * 24 * 60 * 60
     */
    public static final long MONTH_TO_SECONDS = 2592000L;

    /**
     * 一天的时间换算成秒：24 * 60 * 60
     */
    public static final long DAY_TO_SECONDS = 86400L;

    /**
     * 获取当前Date类型时间
     * @return
     */
    public static Date getSysdate() {
        return new Date();
    }

    /**
     * 获取当前String（yyyy-MM-dd HH:mm:ss）类型时间
     * @return
     */
    public static String getSysdateStr() {
        Date date = new Date();
        return format(date, DATE_FORMAT1);
    }

    /**
     * 获取当前String（yyyyMMddHHmmssSSS）类型时间
     * @return
     */
    public static String getSysdateStr19() {
        Date date = new Date();
        return format(date, DATE_FORMAT6);
    }

    /**
     * 获取指定字符串格式的当前时间
     * @param format
     * @return
     */
    public static String getSysdateStr(String format) {
        Date date = new Date();
        return format(date, format);
    }

    /**
     * 格式化日期，格式为“yyyy-MM-dd HH:mm:ss”
     * @param date
     * @return
     */
    public static String format(Date date) {
        return format(date, DateUtils.DATE_FORMAT1);
    }

    /**
     * 格式化日期，格式自定义
     * @param date
     * @param format
     * @return
     */
    public static String format(Date date, String format) {
        if (date == null) {
            return null;
        }
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(format);
    }

    /**
     * 字符串转换成日期，字符串格式同date类型
     * @param dateStr
     * @param format
     * @return
     */
    public static Date parse(String dateStr, String format) {
        if (null == dateStr) {
            return null;
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(format);
        DateTime dateTime = dateTimeFormatter.parseDateTime(dateStr);
        return dateTime.toDate();
    }

    /**
     * 字符串转换成日期
     * @param dateStr
     * @return
     */
    public static Date parse(String dateStr) {
        if (-1 < dateStr.indexOf("-")) {
            return parse(dateStr, "yyyy-MM-dd");
        } else if (-1 < dateStr.indexOf("/")) {
            return parse(dateStr, "yyyy/MM/dd");
        } else {
            return parse(dateStr, "yyyyMMdd");
        }
    }

    /**
     * 判断date日期是否过期(与当前时刻比较)
     *
     * @param date
     * @return
     */
    public static boolean isTimeExpired(Date date) {
        if (null == date) {
            return true;
        }
        String timeStr = format(date);
        return isBeforeNow(timeStr);
    }

    /**
     * 判断date日期是否过期(与当前时刻比较)
     *
     * @param timeStr
     * @return
     */
    public static boolean isTimeExpired(String timeStr) {
        if (StringUtils.isBlank(timeStr)) {
            return true;
        }
        return isBeforeNow(timeStr);
    }

    /**
     * 判断timeStr是否在当前时刻之前
     *
     * @param timeStr
     * @return
     */
    private static boolean isBeforeNow(String timeStr) {
        DateTimeFormatter format = DateTimeFormat.forPattern(DATE_FORMAT1);
        DateTime dateTime = DateTime.parse(timeStr, format);
        return dateTime.isBeforeNow();
    }

    /**
     * 日期加天数
     *
     * @param date
     * @param days
     * @return
     */
    public static Date plusDays(Date date, Integer days) {
        return plusOrMinusDays(date, days, 0);
    }

    /**
     * 日期减天数
     *
     * @param date
     * @param days
     * @return
     */
    public static Date minusDays(Date date, Integer days) {
        return plusOrMinusDays(date, days, 1);
    }

    /**
     * 加减天数
     *
     * @param date
     * @param days
     * @param type 0:加天数 1:减天数
     * @return
     */
    private static Date plusOrMinusDays(Date date, Integer days, Integer type) {
        if (null == date) {
            return null;
        }
        days = null == days ? 0 : days;

        DateTime dateTime = new DateTime(date);
        if (type == 0) {
            dateTime = dateTime.plusDays(days);
        } else {
            dateTime = dateTime.minusDays(days);
        }

        return dateTime.toDate();
    }

    /**
     * 日期加分钟
     *
     * @param date
     * @param minutes
     * @return
     */
    public static Date plusMinutes(Date date, Integer minutes) {
        return plusOrMinusMinutes(date, minutes, 0);
    }

    /**
     * 日期减分钟
     *
     * @param date
     * @param minutes
     * @return
     */
    public static Date minusMinutes(Date date, Integer minutes) {
        return plusOrMinusMinutes(date, minutes, 1);
    }

    /**
     * 加减分钟
     *
     * @param date
     * @param minutes
     * @param type    0:加分钟 1:减分钟
     * @return
     */
    private static Date plusOrMinusMinutes(Date date, Integer minutes, Integer type) {
        if (null == date) {
            return null;
        }
        minutes = null == minutes ? 0 : minutes;

        DateTime dateTime = new DateTime(date);
        if (type == 0) {
            dateTime = dateTime.plusMinutes(minutes);
        } else {
            dateTime = dateTime.minusMinutes(minutes);
        }

        return dateTime.toDate();
    }

    /**
     * 日期加月份
     *
     * @param date
     * @param months
     * @return
     */
    public static Date plusMonths(Date date, Integer months) {
        return plusOrMinusMonths(date, months, 0);
    }

    /**
     * 日期减月份
     *
     * @param date
     * @param months
     * @return
     */
    public static Date minusMonths(Date date, Integer months) {
        return plusOrMinusMonths(date, months, 1);
    }

    /**
     * 加减月份
     *
     * @param date
     * @param months
     * @param type   0:加月份 1:减月份
     * @return
     */
    private static Date plusOrMinusMonths(Date date, Integer months, Integer type) {
        if (null == date) {
            return null;
        }
        months = null == months ? 0 : months;

        DateTime dateTime = new DateTime(date);
        if (type == 0) {
            dateTime = dateTime.plusMonths(months);
        } else {
            dateTime = dateTime.minusMonths(months);
        }

        return dateTime.toDate();
    }

    /**
     * 判断target是否在开始和结束时间之间
     *
     * @param target
     * @param startTime
     * @param endTime
     * @return
     */
    public static boolean isBetweenStartAndEndTime(Date target, Date startTime, Date endTime) {
        if (null == target || null == startTime || null == endTime) {
            return false;
        }

        DateTime dateTime = new DateTime(target);
        return dateTime.isAfter(startTime.getTime()) && dateTime.isBefore(endTime.getTime());
    }
}
