日期工具类

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.util.StringUtils;
import tv.zhongchi.common.exception.BizException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * @ClassName DateUtil
 * @Author ZhangRF
 * @CreateDate 2020/6/12
 * @Decription 时间工具类
 */
public class DateUtil {
    public static final long ONE_HOUR_TIME_LONG = 3600000;

    /**
     * 年(yyyy)
     */
    public static final String YEAR = "yyyy";

    /**
     * 年-月(yyyy-MM)
     */
    public static final String YEAR_MONTH = "yyyy-MM";

    /**
     * 年-月-日(yyyy-MM-dd)
     */
    public static final String YEAR_MONTH_DAY = "yyyy-MM-dd";

    /**
     * 年月日(yyyyMMdd)
     */
    public static final String YEAR_MONTH_DAY_SIMPLE = "yyyyMMdd";

    /**
     * 年-月-日 小时(yyyy-MM-dd HH)
     */
    public static final String YEAR_MONTH_DAY_HOUR = "yyyy-MM-dd HH";

    /**
     * 年-月-日 小时(yyyy-MM-dd HH)中文输出
     */
    public static final String YEAR_MONTH_DAY_HOUR_CN = "yyyy年MM月dd日HH时";

    /**
     * 年-月-日 小时:分钟(yyyy-MM-dd HH:mm)
     */
    public static final String YEAR_MONTH_DAY_HOUR_MINUTE = "yyyy-MM-dd HH:mm";

    /**
     * 年-月-日 小时:分钟:秒钟(yyyy-MM-dd HH:mm:ss)
     */
    public static final String YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";

    /**
     * 年月日小时分钟(yyMMddHHmm)订单
     */
    public static final String YEAR_MONTH_DAY_HOUR_MINUTE_ORDER = "yyMMddHHmm";

    /**
     * 年月日小时分钟秒钟(yyyyMMddHHmmss)
     */
    public static final String YEAR_MONTH_DAY_HOUR_MINUTE_SECOND_SIMPLE = "yyyyMMddHHmmss";

    /**
     * 小时:分钟:秒钟(HH:mm:ss)
     */
    public static final String HOUR_MINUTE_SECOND = "HH:mm:ss";

    /**
     * 小时:分钟(HH:mm)
     */
    public static final String HOUR_MINUTE = "HH:mm";

    /**
     * 月.日(M.d)
     */
    public static final String MONTH_DAY = "M.d";
    public static final String REG_EXP_DATE = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
    /**
     * 一天的秒数
     */
    private static final int DAY_SECOND = 24 * 60 * 60;
    /**
     * 一小时的秒数
     */
    private static final int HOUR_SECOND = 60 * 60;
    /**
     * 一分钟的秒数
     */
    private static final int MINUTE_SECOND = 60;

    public DateUtil() {
        System.setProperty("user.timezone", "Asia/Shanghai");
    }

    /**
     * 获取当前时间
     *
     * @return 返回当前时间
     */
    public static Date getCurrent() {
        return new Date();
    }

    /**
     * 获取当前时间并格式化
     *
     * @return 返回当前时间
     */
    public static String getCurrentDate(String format) {
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(d);
    }

    /**
     * 获取下个月时间并格式化
     *
     * @return 返回当前时间
     */
    public static String getNextDate(String format) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 1);
        SimpleDateFormat dft = new SimpleDateFormat(format);
        String preMonth = dft.format(cal.getTime());
        return preMonth;
    }

    /**
     * 格式化日期时间
     *
     * @param date    Date对象
     * @param pattern 模式
     * @return 格式化后的日期时间字符串
     */
    public static String format(Date date, String pattern) {
        if (date == null)
            return "";
        return new DateTime(date).toString(pattern);
    }

    /**
     * 格式化日期时间字符串
     *
     * @param dateString 日期时间字符串
     * @param pattern    模式
     * @return Date对象
     */
    public static Date formatDateString(String dateString, String pattern) {
        try {
            DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(pattern);
            return dateTimeFormatter.parseDateTime(dateString).toDate();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 根据秒数获得x天x小时x分钟x秒字符串
     *
     * @param second 秒数
     * @return x天x小时x分钟x秒字符串
     */
    public static String getDayHourMinuteSecond(int second) {
        if (second == 0) {
            return "0秒";
        }
        StringBuilder sb = new StringBuilder();
        int days = second / DAY_SECOND;
        if (days > 0) {
            sb.append(days);
            sb.append("天");
            second -= days * DAY_SECOND;
        }

        int hours = second / HOUR_SECOND;
        if (hours > 0) {
            sb.append(hours);
            sb.append("小时");
            second -= hours * HOUR_SECOND;
        }

        int minutes = second / MINUTE_SECOND;
        if (minutes > 0) {
            sb.append(minutes);
            sb.append("分钟");
            second -= minutes * MINUTE_SECOND;
        }
        if (second > 0) {
            sb.append(second);
            sb.append("秒");
        }
        return sb.toString();
    }

    /**
     * 根据秒数获得x天x小时x分钟字符串
     *
     * @param second 秒数
     * @return x天x小时x分钟字符串
     */
    public static String getDayHourMinute(int second) {
        if (second == 0) {
            return "0分钟";
        }
        StringBuilder sb = new StringBuilder();
        int days = second / DAY_SECOND;
        if (days > 0) {
            sb.append(days);
            sb.append("天");
            second -= days * DAY_SECOND;
        }

        int hours = second / HOUR_SECOND;
        if (hours > 0) {
            sb.append(hours);
            sb.append("小时");
            second -= hours * HOUR_SECOND;
        }
        int minutes = second / MINUTE_SECOND;
        if (minutes > 0) {
            sb.append(minutes);
            sb.append("分钟");
        }
        return sb.toString();
    }

    /**
     * 获取只含有年月日的DateTime对象
     *
     * @param dateTime DateTime对象
     * @return 只含有年月日的DateTime对象
     */
    public static DateTime getDateOnly(DateTime dateTime) {
        return new DateTime(dateTime.toString(YEAR_MONTH_DAY));
    }

    /**
     * 获取当前周的周一和下周一
     *
     * @return 日期数组(索引0为周一,索引1为下周一)
     */
    public static Date[] getMondayAndNextMonday() {
        DateTime dateTime = getDateOnly(new DateTime());
        DateTime monday = dateTime.dayOfWeek().withMinimumValue();
        DateTime nextMonday = monday.plusDays(7);
        return new Date[]{monday.toDate(), nextMonday.toDate()};
    }

    /**
     * 获取指定时间的周一和周日
     *
     * @param dateTime DateTime对象
     * @return 日期数组(索引0为周一,索引1为周日)
     */
    public static Date[] getMondayAndSunday(DateTime dateTime) {
        dateTime = getDateOnly(dateTime);
        DateTime monday = dateTime.dayOfWeek().withMinimumValue();
        DateTime sunday = monday.plusDays(6);
        return new Date[]{monday.toDate(), sunday.toDate()};
    }

    /**
     * 和今天相比的天数差(正数为大于天数,负数为小于天数,零为同一天)
     *
     * @param date Date对象
     * @return 和今天相比的天数差
     */
    public static int compareDaysWithToday(Date date) {
        DateTime today = new DateTime();
        today = new DateTime(today.getYear(), today.getMonthOfYear(), today.getDayOfMonth(), 0, 0, 0, 0);
        DateTime compareDay = new DateTime(date);
        compareDay = new DateTime(compareDay.getYear(), compareDay.getMonthOfYear(), compareDay.getDayOfMonth(), 0, 0, 0, 0);
        return Days.daysBetween(today, compareDay).getDays();
    }

    /**
     * 比较时间a到时间b的天数差
     *
     * @param a 时间a
     * @param b 时间b
     * @return 相差天数
     */
    public static int compareDaysWithDay(Date a, Date b) {
        DateTime today = new DateTime(b);
        today = new DateTime(today.getYear(), today.getMonthOfYear(), today.getDayOfMonth(), 0, 0, 0, 0);
        DateTime compareDay = new DateTime(a);
        compareDay = new DateTime(compareDay.getYear(), compareDay.getMonthOfYear(), compareDay.getDayOfMonth(), 0, 0, 0, 0);
        return Days.daysBetween(today, compareDay).getDays();
    }

    /**
     * 比较两个时间是否相等(省略毫秒)
     *
     * @param date        Date对象
     * @param compareDate 比较Date对象
     * @return 是否相等
     */
    public static boolean compareDateIgnoreMillisecond(Date date, Date compareDate) {
        if (date == null && compareDate == null) {
            return true;
        } else if (date == null && compareDate != null) {
            return false;
        } else if (date != null && compareDate == null) {
            return false;
        }

        return (date.getTime() / 1000 == compareDate.getTime() / 1000);
    }

    /**
     * 根据秒数获取天数
     *
     * @param second 秒数
     * @return 天数
     */
    public static int getDay(int second) {
        return second / DAY_SECOND;
    }

    /**
     * 获取和今天相比的日期字符串
     *
     * @param date Date对象
     * @return 和今天相比的日期字符串
     */
    public static String getCompareWithTodayDateString(Date date) {
        int days = Math.abs(DateUtil.compareDaysWithToday(date));
        String dateString = "";
        if (days == 0) {
            dateString = "今天";
        } else if (days == 1) {
            dateString = "昨天";
        } else if (days == 2) {
            dateString = "2天前";
        } else if (days == 3) {
            dateString = "3天前";
        } else if (days == 4) {
            dateString = "4天前";
        } else if (days == 5) {
            dateString = "5天前";
        } else if (days == 6) {
            dateString = "6天前";
        } else if (days > 6 && days <= 14) {
            dateString = "1周前";
        } else if (days > 14 && days <= 21) {
            dateString = "2周前";
        } else if (days > 21 && days <= 30) {
            dateString = "3周前";
        } else if (days > 30) {
            dateString = "1月前";
        } else if (days > 365) {
            dateString = "1年前";
        } else if (days > 365 * 3) {
            dateString = "3年前";
        }
        return dateString;
    }

    /**
     * 比较两个时间相差分钟数
     *
     * @param now         当前时间
     * @param compareDate 比较时间
     * @return 相差分钟数
     */
    public static int compareMinutes(Date now, Date compareDate) {
        return (int) (now.getTime() - compareDate.getTime()) / 60000;
    }

    /**
     * 比较时间是本月的第几天
     *
     * @param date
     * @return
     */
    public static int getDayOfMonth(Date date) {
        DateTime dateTime = new DateTime(date);
        return dateTime.getDayOfMonth();
    }

    /**
     * 计算今天是今年第几天
     *
     * @return
     */
    public static Integer todayYearDayNum() {
        return -compareDaysWithToday(parse(year(new Date()) - 1 + "-12-31"));
    }

    /**
     * 计算当月有几天
     *
     * @param date
     * @return
     */
    public static int getDateOfMonth(Date date) {
        DateTime dateTime = new DateTime(date);
        return dateTime.dayOfMonth().getMaximumValue();
    }

    /**
     * 指定时间,判断该时间到现在时间的年数
     *
     * @param date 指定时间
     * @return 到现在时间的年数
     */
    public static int compareYear(Date date) {
        DateTime btd = new DateTime(date);
        DateTime nowDate = new DateTime();
        int year = 0;
        if (nowDate.getMonthOfYear() > btd.getMonthOfYear()) {
            year = nowDate.getYear() - btd.getYear();
        } else if (nowDate.getMonthOfYear() < btd.getMonthOfYear()) {
            year = nowDate.getYear() - btd.getYear() - 1;
        } else if (nowDate.getMonthOfYear() == btd.getMonthOfYear()) {
            if (nowDate.getDayOfMonth() >= btd.getDayOfMonth()) {
                year = nowDate.getYear() - btd.getYear();
            } else {
                year = nowDate.getYear() - btd.getYear() - 1;
            }
        }
        return year;
    }

    /**
     * 获取两个日期相差的月数
     */
    public static int getMonthDiff(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        int year1 = c1.get(Calendar.YEAR);
        int year2 = c2.get(Calendar.YEAR);
        int month1 = c1.get(Calendar.MONTH);
        int month2 = c2.get(Calendar.MONTH);
        int day1 = c1.get(Calendar.DAY_OF_MONTH);
        int day2 = c2.get(Calendar.DAY_OF_MONTH);
        // 获取年的差值
        int yearInterval = year1 - year2;
        // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
        if (month1 < month2 || month1 == month2 && day1 < day2) {
            yearInterval--;
        }
        // 获取月数差值
        int monthInterval = (month1 + 12) - month2;
        if (day1 < day2) {
            monthInterval--;
        }
        monthInterval %= 12;
        int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
        return monthsDiff;
    }

    /**
     * 两指定时间之间的年份
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static int compareYear(Date startDate, Date endDate) {
        DateTime btd = new DateTime(startDate);
        DateTime nowDate = new DateTime(endDate);
        int year = 0;
        if (nowDate.getMonthOfYear() > btd.getMonthOfYear()) {
            year = nowDate.getYear() - btd.getYear();
        } else if (nowDate.getMonthOfYear() < btd.getMonthOfYear()) {
            year = nowDate.getYear() - btd.getYear() - 1;
        } else if (nowDate.getMonthOfYear() == btd.getMonthOfYear()) {
            if (nowDate.getDayOfMonth() >= btd.getDayOfMonth()) {
                year = nowDate.getYear() - btd.getYear();
            } else {
                year = nowDate.getYear() - btd.getYear() - 1;
            }
        }
        return year;
    }

    /**
     * 判断2个时间的时间差 返回字符串形式
     *
     * @param date  要对比的字符串
     * @param date2 要对比的字符串
     * @return 字符串形式 如1小时 ,2天2小时
     */
    public static String compareDaysWithDate(Date date, Date date2) {
        StringBuilder msg = new StringBuilder();
        int minutes = (int) Math.abs((date.getTime() - date2.getTime()) / 60000);
        if (minutes / 60 > 0 && minutes / 60 / 24 <= 0) {
            msg.append(minutes / 60 + "小时");
        }
        if (minutes / 60 / 24 > 0) {
            msg.append(minutes / 60 / 24 + "天");
            msg.append(minutes / 60 % 24 + "小时");
        }
        return msg.toString();
    }

    /**
     * 自动解析多种格式的时间字符串为时间对象<br>
     * 支持格式为:yyyy-MM-dd HH:mm:ss 支持多种分隔符,以及多种日期精度。 如yyyy年MM月。 HH时mm分ss秒
     *
     * @param dateString 时间字符串 <br>
     * @return 格式正确则返回对应的java.util.Date对象 格式错误返回null
     */
    public static Date formatUnknownString2Date(String dateString) {
        try {
            if (StringUtil.isEmpty(dateString)) {
                return null;
            }
            dateString = dateString.replace("T", " ");
            String hms = "00:00:00";
            dateString = dateString.trim();
            if (dateString.contains(" ")) {
                // 截取时分秒
                hms = dateString.substring(dateString.indexOf(" ") + 1);
                // 重置日期
                dateString = dateString.substring(0, dateString.indexOf(" "));
                // 多中分隔符的支持
                hms = hms.replace(":", ":");
                hms = hms.replace("时", ":");
                hms = hms.replace("分", ":");
                hms = hms.replace("秒", ":");
                hms = hms.replace("-", ":");
                hms = hms.replace("-", ":");
                // 时间不同精确度的支持
                if (hms.endsWith(":")) {
                    hms = hms.substring(0, hms.length() - 1);
                }
                if (hms.split(":").length == 1) {
                    hms += ":00:00";
                }
                if (hms.split(":").length == 2) {
                    hms += ":00";
                }
            }
            String[] hmsarr = hms.split(":");
            // 不同日期分隔符的支持
            dateString = dateString.replace(".", "-");
            dateString = dateString.replace("/", "-");
            dateString = dateString.replace("-", "-");
            dateString = dateString.replace("年", "-");
            dateString = dateString.replace("月", "-");
            dateString = dateString.replace("日", "");
            // 切割年月日
            String yearStr, monthStr, dateStr;
            // 截取日期
            String[] ymd = dateString.split("-");
            // 判断日期精确度
            yearStr = ymd[0];
            monthStr = ymd.length > 1 ? ymd[1] : "";
            dateStr = ymd.length > 2 ? ymd[2] : "";
            monthStr = monthStr == "" ? Integer.toString(1) : monthStr;
            if (monthStr.length() == 1) {
                monthStr = 0 + monthStr;
            }
            dateStr = dateStr == "" ? Integer.toString(1) : dateStr;
            if (dateStr.length() == 1) {
                dateStr = 0 + dateStr;
            }
            String dtr = (yearStr + "-" + monthStr + "-" + dateStr + " " + hms);
            if (!dtr.matches(REG_EXP_DATE))
                return null;
            // 返回日期
            return new DateTime(Integer.parseInt(yearStr.trim()), Integer.parseInt(monthStr.trim()), Integer.parseInt(dateStr.trim()), Integer.parseInt(hmsarr[0].trim()), Integer.parseInt(hmsarr[1].trim()), Integer.parseInt(hmsarr[2].trim()), 0).toDate();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 解析多个时间,指定时间之间的分隔符和时间的格式符 分隔符不能与格式符相同
     *
     * @param dateString 传入一个时间段字符串
     * @param spaceChar  指定格式符
     * @param splitChar  指定分隔符
     * @return 格式正确返回分割后的时间对象数组 格式错误返回null <br>
     * 指定了格式符为. 分隔符为- 返回值为 时间长度为2的Date类型数组<br>
     * 时间转换的方式详见 {@link DateTimeUtils#formatUnknownString2Date(String dateString)}
     */
    public static Date[] formatDatesByString(String dateString, String spaceChar, String splitChar) {
        if (spaceChar.equals(splitChar)) {
            return null;
        }
        String[] dateStrs = dateString.split(splitChar);
        Date[] dates = new Date[dateStrs.length];
        for (int i = 0, size = dateStrs.length; i < size; i++) {
            dates[i] = formatUnknownString2Date(dateStrs[i]);
        }
        return dates;
    }

    /**
     * 身份证号转生日
     *
     * @param identityCard 身份证
     * @return 生日
     */
    public static Date identityCard2Date(String identityCard) {
        try {
            String dateStr;
            if (identityCard.length() == 18) {
                dateStr = identityCard.substring(6, 14);// 截取18位身份证身份证中生日部分
                return formatDateString(dateStr, "yyyyMMdd");
            }
            if (identityCard.length() == 15) {
                dateStr = identityCard.substring(6, 12);// 截取15位身份证中生日部分
                return formatDateString(dateStr, "yyMMdd");
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

    public static boolean validDate(String str) {
        try {
            Date date = formatUnknownString2Date(str);
            return date != null;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 根据周数,获取开始日期、结束日期
     *
     * @param week 周期  0本周,-1上周,-2上上周,1下周,2下下周
     * @return 返回date[0]开始日期、date[1]结束日期
     */
    public static Date[] getWeekStartAndEnd(int week) {
        DateTime dateTime = new DateTime();
        LocalDate date = new LocalDate(dateTime.plusWeeks(week));

        date = date.dayOfWeek().withMinimumValue();
        Date beginDate = date.toDate();
        Date endDate = date.plusDays(6).toDate();
        return new Date[]{beginDate, endDate};
    }

    /**
     * 对日期的【秒】进行加/减
     *
     * @param date    日期
     * @param seconds 秒数,负数为减
     * @return 加/减几秒后的日期
     */
    public static Date addDateSeconds(Date date, int seconds) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusSeconds(seconds).toDate();
    }

    /**
     * 对日期的【分钟】进行加/减
     *
     * @param date    日期
     * @param minutes 分钟数,负数为减
     * @return 加/减几分钟后的日期
     */
    public static Date addDateMinutes(Date date, int minutes) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMinutes(minutes).toDate();
    }

    /**
     * 对日期的【小时】进行加/减
     *
     * @param date  日期
     * @param hours 小时数,负数为减
     * @return 加/减几小时后的日期
     */
    public static Date addDateHours(Date date, int hours) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusHours(hours).toDate();
    }

    /**
     * 对日期的【天】进行加/减
     *
     * @param date 日期
     * @param days 天数,负数为减
     * @return 加/减几天后的日期
     */
    public static Date addDateDays(Date date, int days) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusDays(days).toDate();
    }

    /**
     * 对日期的【周】进行加/减
     *
     * @param date  日期
     * @param weeks 周数,负数为减
     * @return 加/减几周后的日期
     */
    public static Date addDateWeeks(Date date, int weeks) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusWeeks(weeks).toDate();
    }

    /**
     * 对日期的【月】进行加/减
     *
     * @param date   日期
     * @param months 月数,负数为减
     * @return 加/减几月后的日期
     */
    public static Date addDateMonths(Date date, int months) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMonths(months).toDate();
    }

    /**
     * 对日期的【年】进行加/减
     *
     * @param date  日期
     * @param years 年数,负数为减
     * @return 加/减几年后的日期
     */
    public static Date addDateYears(Date date, int years) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusYears(years).toDate();
    }

    public static String toString(Date date, String format) {
        String dateStr = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            dateStr = sdf.format(date);
        } catch (Exception e) {
        }
        return dateStr;
    }

    public static Date parseDate(String dateStr, String format) {
        Date date = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            date = sdf.parse(dateStr);
        } catch (Exception e) {
        }
        return date;
    }

    /**
     * 获取日期当天的最小时间日期,0点
     */
    public static Date getMinTimeDateByDate(Date date) {
        if (date == null)
            return null;
        String datestr = toString(date, "yyyyMMdd");
        return parseDate(datestr, "yyyyMMdd");
    }

    /**
     * 获取日期当天的最大时间日期,12点整
     */
    public static Date getMaxTimeDateByDate(Date date) {
        if (date == null)
            return null;
        String datestr = toString(date, "yyyyMMdd");
        Date d = parseDate(datestr, "yyyyMMdd");
        return new Date(d.getTime() + 24L * 60L * 60L * 1000L - 1L);
    }

    public static long subTime(Date startDate, Date endDate) {
        return endDate.getTime() - startDate.getTime();
    }

    public static long getTime(Date date) {
        return date.getTime();
    }

    /**
     * 获取上月第一天最早时间
     *
     * @return Date
     */
    public static Date getLastMonthFirstDay() {
        Calendar cal_1 = Calendar.getInstance();// 获取当前日期
        cal_1.setTime(getMinTimeDateByDate(new Date()));
        cal_1.add(Calendar.MONTH, -1);
        cal_1.set(Calendar.DAY_OF_MONTH, 1);
        return cal_1.getTime();
    }

    /**
     * 获取上月最后一天最晚时间
     *
     * @return Date
     */
    public static Date getLastMonthLastDay() {
        Calendar cale = Calendar.getInstance();
        cale.setTime(getMinTimeDateByDate(new Date()));
        cale.add(Calendar.MONTH, -1);
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DAY_OF_MONTH));
        return new Date(cale.getTime().getTime() + 1000L * 60L * 60L * 24L - 1L);
    }

    /**
     * 获取本月第一天最早时间
     *
     * @return Date
     */
    public static Date getNowMonthFirstDay() {
        Calendar cal_1 = Calendar.getInstance();// 获取当前日期
        cal_1.setTime(getMinTimeDateByDate(new Date()));
        cal_1.add(Calendar.MONTH, 0);
        cal_1.set(Calendar.DAY_OF_MONTH, 1);
        return cal_1.getTime();
    }

    /**
     * 获取本月最后一天最晚时间
     *
     * @return Date
     */
    public static Date getNowMonthLastDay() {
        Calendar cale = Calendar.getInstance();
        cale.setTime(getMinTimeDateByDate(new Date()));
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DAY_OF_MONTH));
        return new Date(cale.getTime().getTime() + 1000L * 60L * 60L * 24L - 1L);
    }

    /**
     * 获取月最后一天最晚时间
     *
     * @return Date
     */
    public static Date getNowMonthLastDay(Date date) {
        Calendar cale = Calendar.getInstance();
        cale.setTime(getMinTimeDateByDate(date));
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DAY_OF_MONTH));
        return new Date(cale.getTime().getTime() + 1000L * 60L * 60L * 24L - 1L);
    }

    /**
     * 获取本月最后一天
     *
     * @return Date
     */
    public static Date getTheMonthLastDay(Date date) {
        if (date == null) {
            return null;
        }
        Calendar cale = Calendar.getInstance();
        cale.setTime(date);
        cale.set(Calendar.DAY_OF_MONTH, cale.getActualMaximum(Calendar.DAY_OF_MONTH));
        cale.set(Calendar.HOUR, 0);
        cale.set(Calendar.HOUR_OF_DAY, 0);
        cale.set(Calendar.MINUTE, 0);
        cale.set(Calendar.SECOND, 0);
        cale.set(Calendar.MILLISECOND, 0);
        return cale.getTime();
    }

    /**
     * 获取格式化的时间,默认是yyyy-MM-dd HH:mm:ss此格式
     *
     * @return
     */
    public static String GetFormatTime() {
        DateTime dateTime = new DateTime().withZone(DateTimeZone.forID("Asia/Shanghai")).toLocalDateTime().toDateTime();
        try {
            return dateTime.toString("yyyy-MM-dd HH:mm:ss");
        } catch (Exception ex) {
            ex.printStackTrace();
            return dateTime.toString();
        }
    }

    /**
     * 获取格式化的时间
     *
     * @param formatter 时间格式化字符串
     * @return
     */
    public static String GetFormatTime(String formatter) {
        DateTime dateTime = new DateTime().withZone(DateTimeZone.forID("Asia/Shanghai")).toLocalDateTime().toDateTime();
        try {
            return dateTime.toString(formatter);
        } catch (Exception ex) {
            ex.printStackTrace();
            return dateTime.toString("yyyy-MM-dd HH:mm:ss");
        }
    }

    /**
     * 获取格式化的时间字符串
     *
     * @param formatTime 自定义时间
     * @param formatter  格式化规则
     * @return
     */
    public static String GetFormatTime(Date formatTime, String formatter) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatter);
        try {
            return sdf.format(formatTime);
        } catch (Exception ex) {
            return GetFormatTime(formatter);
        }
    }

    public static String GetFormatTime(Date formatTime) {
//        YEAR_MONTH_DAY_HOUR_MINUTE
        SimpleDateFormat sdf = new SimpleDateFormat(YEAR_MONTH_DAY_HOUR_MINUTE);
        try {
            return sdf.format(formatTime);
        } catch (Exception ex) {
            return GetFormatTime(YEAR_MONTH_DAY_HOUR_MINUTE);
        }
    }

    /**
     * 短时间变长时间
     *
     * @param tmp 格式:20190301
     * @return
     */
    public static String sortTimeToLongTime(String tmp) {
        return tmp.substring(0, 4) + "-" + tmp.substring(4, 6) + "-" + tmp.substring(6, 8);
    }

    /**
     * 获取今天开始时间
     *
     * @return
     */
    public static Date getTodayStart() {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.parse(sdf.format(new Date()));
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 获取今天结束时间
     *
     * @return
     */
    public static Date getTodayEnd() {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(new Date().getTime()),
                ZoneId.systemDefault());
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date parse(String strDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return sdf.parse(strDate);
        } catch (Exception e) {
        }
        return null;
    }

    public static Integer year(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            String format = sdf.format(date);
            return Integer.valueOf(format.substring(0, 4));
        } catch (Exception e) {
        }
        return null;
    }

    public static Integer month(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            String format = sdf.format(date);
            return Integer.valueOf(format.substring(5, 7));
        } catch (Exception e) {
        }
        return null;
    }

    public static Integer day(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            String format = sdf.format(date);
            return Integer.valueOf(format.substring(9, 10));
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 时分秒转int
     *
     * @param time hh:mm:ss
     * @return hhmmss
     */
    public static Integer getIntTime(String time) {
        if (time.contains("-")) {
            throw new BizException("时间参数错误,请重试");
        }
        boolean a = time.contains(":");
        boolean b = time.contains(":");
        List<String> list = new ArrayList<>();
        if (!a && !b) {
            throw new BizException("时间参数错误,请重试");
        }
        if (a && !b) {
            String[] split = time.split(":");
            list.addAll(Arrays.asList(split));
        }
        if (!a && b) {
            String[] split = time.split(":");
            list.addAll(Arrays.asList(split));
        }
        if (a && b) {
            String[] split = time.split(":");
            for (String s : split) {
                String[] split1 = s.split(":");
                list.addAll(Arrays.asList(split1));
            }
        }
        StringBuilder times = new StringBuilder();
        for (String s : list) {
            times.append(s);
        }
        return Integer.valueOf(times.toString());
    }

    /**
     * 获取周日历
     *
     * @param date 当前时间
     * @param week 0:当前周,负数为减
     * @return 加/减几周后的日期
     */
    public static List<Date> dateList(Date date, int week) {
        Date dateWeek = addDateWeeks(date, week);
        DateTime dateTime = new DateTime(dateWeek.getTime());
        Date[] mondayAndSunday = getMondayAndSunday(dateTime);
        Date weekOne = mondayAndSunday[0];

        List<Date> weekDayList = new ArrayList<>();
        for (int i = 0; i <= 6; i++) {
            weekDayList.add(addDateDays(weekOne, i));
        }
        return weekDayList;
    }

    /**
     * 根据类型解析开始时间
     *
     * @param beginTime 开始时间
     * @param type      类型:1:日、2:周、3:月、4:年
     * @return
     */
    public static String getBeginTime(String beginTime, Integer type) {
        if (type == null) {
            throw new BizException("时间类型参数不能为空");
        }

        if (StringUtils.isEmpty(beginTime)) {
            beginTime = GetFormatTime(getTodayStart(), DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
        }

        if (type == 1) {
            if (beginTime.length() < 10) {
                throw new BizException("开始时间参数错误;参数为:" + beginTime);
            }
            beginTime = beginTime.substring(0, 10) + " 00:00:00";
        } else if (type == 2) {
            if (beginTime.length() < 10) {
                throw new BizException("开始时间参数错误;参数为:" + beginTime);
            }
            beginTime = beginTime.substring(0, 10) + " 00:00:00";
        } else if (type == 3) {
            if (beginTime.length() < 7) {
                throw new BizException("开始时间参数错误;参数为:" + beginTime);
            }
            beginTime = beginTime.substring(0, 7) + "-01 00:00:00";
        } else if (type == 4) {
            if (beginTime.length() < 4) {
                throw new BizException("开始时间参数错误;参数为:" + beginTime);
            }
            beginTime = beginTime.substring(0, 4) + "-01-01 00:00:00";
        }
        return beginTime;
    }

    /**
     * 解析开始时间
     *
     * @param beginTime
     * @return
     */
    public static String getBeginTime(String beginTime) {
        if (StringUtils.isEmpty(beginTime)) {
            beginTime = GetFormatTime(getTodayStart(), DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
        } else if (beginTime.length() < 4) {
            throw new BizException("时间格式错误");
        } else if (beginTime.length() == 4) {
            beginTime = beginTime.substring(0, 4) + "-01-01 00:00:00";
        } else if (beginTime.length() >= 7 && beginTime.length() < 10) {
            beginTime = beginTime.substring(0, 7) + "-01 00:00:00";
        } else if (beginTime.length() >= 10) {
            beginTime = beginTime.substring(0, 10) + " 00:00:00";
        }
        return beginTime;
    }

    /**
     * 根据类型解析结束时间
     *
     * @param endTime 结束时间
     * @param type    类型:1:日、2:周、3:月、4:年
     * @return
     */
    public static String getEndTime(String endTime, Integer type) {
        if (type == null) {
            throw new BizException("时间类型参数不能为空");
        }

        if (StringUtils.isEmpty(endTime)) {
            endTime = GetFormatTime(getTodayEnd(), DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
        }

        if (type == 1) {
            if (endTime.length() < 10) {
                throw new BizException("结束时间参数错误;参数为:" + endTime);
            }
            endTime = endTime.substring(0, 10) + " 23:59:59";
        } else if (type == 2) {
            if (endTime.length() < 10) {
                throw new BizException("结束时间参数错误;参数为:" + endTime);
            }
            endTime = endTime.substring(0, 10) + " 23:59:59";
        } else if (type == 3) {
            if (endTime.length() < 7) {
                throw new BizException("结束时间参数错误;参数为:" + endTime);
            }
            endTime = GetFormatTime(getNowMonthLastDay(formatDateString(endTime.substring(0, 7), YEAR_MONTH)), YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
        } else if (type == 4) {
            if (endTime.length() < 4) {
                throw new BizException("结束时间参数错误;参数为:" + endTime);
            }
            endTime = endTime.substring(0, 4) + "-12-31 23:59:59";
        }
        return endTime;
    }

    /**
     * 解析结束时间
     *
     * @param endTime
     * @return
     */
    public static String getEndTime(String endTime) {
        if (StringUtils.isEmpty(endTime)) {
            endTime = GetFormatTime(getTodayEnd(), DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
        } else if (endTime.length() < 4) {
            throw new BizException("时间格式错误");
        } else if (endTime.length() == 4) {
            endTime = endTime.substring(0, 4) + "-12-31 23:59:59";
        } else if (endTime.length() >= 7 && endTime.length() < 10) {
            endTime = GetFormatTime(getNowMonthLastDay(formatDateString(endTime.substring(0, 7), YEAR_MONTH)), YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
        } else if (endTime.length() >= 10) {
            endTime = endTime.substring(0, 10) + " 23:59:59";
        }
        return endTime;
    }

    /**
     * 计算两个时间之间相差  改方法只有计算目标值使用!!!!其他方法请勿使用
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return {{year=0,month=1,  days=3}
     */
    public static Map<String, Long> getTerm(java.time.LocalDate startDate, java.time.LocalDate endDate) {
        HashMap<String, Long> map = new HashMap<>();
        try {
            int startYear = startDate.getYear();
            int startMonth = startDate.getMonthValue();
            int startDay = startDate.getDayOfMonth();
            int endYear = endDate.getYear();
            int endMonth = endDate.getMonthValue();
            int endDay = endDate.getDayOfMonth();

            java.time.LocalDate nowStartMonth = startDate.with(TemporalAdjusters.firstDayOfMonth());
            java.time.LocalDate nowEndMonth = endDate.with(TemporalAdjusters.lastDayOfMonth());

            //获取两个日期间隔年
            long y = ChronoUnit.YEARS.between(startDate, endDate);
            //获取两个日期间隔月
            long m = ChronoUnit.MONTHS.between(nowStartMonth, nowEndMonth);
            //获取两个日期间隔天
            long d = ChronoUnit.DAYS.between(startDate, endDate);
            //获取某个月的最后一天
            int lastDayOfEndDate = endDate.with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();
            if (startYear == endYear) {
                if (startDay == endDay || lastDayOfEndDate == endDay) {
                    m = endMonth - startMonth;
                } else {
                    //获取传入时间对象的Day值
                    d = endDate.getDayOfMonth();
                }
            } else {
                if (startDay == endDay || lastDayOfEndDate == endDay) {
                    d = 0;
                } else {
                    d = endDate.getDayOfMonth();
                }
            }
            map.put("year", y);
            map.put("month", m);
            map.put("day", d);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    public static int getOneYearDay(int year) {
        int days;//某年(year)的天数
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {//闰年的判断规则
            days = 366;
        } else {
            days = 365;
        }
        return days;
    }

    public static int intervalJudgment(String restBeginTime, String restEndTime, String beginTime, String endTime) {
        if (StringUtil.isEmpty(restBeginTime) || StringUtil.isEmpty(restEndTime)) {
            return 1;
        }
        if (isEffectiveDate(parseDate(beginTime, DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE), parseDate(restBeginTime, DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE), parseDate(restEndTime, DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE))) {
            return 2;
        }
        if (isEffectiveDate(parseDate(endTime, DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE), parseDate(restBeginTime, DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE), parseDate(restEndTime, DateUtil.YEAR_MONTH_DAY_HOUR_MINUTE))) {
            return 2;
        }
        return 1;
    }

    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    public static int getHourByCalendar(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int hour = cal.get(Calendar.HOUR);//小时
        int minute = cal.get(Calendar.MINUTE);//
        return hour;
    }

    /**
     * 获取两个日期之间的所有日期(字符串格式, 按天计算)
     *
     * @param startTime String 开始时间 yyyy-MM-dd
     * @param endTime   String 结束时间 yyyy-MM-dd
     * @return
     */
    public static List<String> getBetweenDays(String startTime, String endTime) {
        if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
            return new ArrayList<>();
        }
        //1、定义转换格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        Date start = null;
        Date end = null;
        try {
            start = df.parse(startTime);
            end = df.parse(endTime);

        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (StringUtil.isEmpty(start) || StringUtil.isEmpty(end)) {
            return new ArrayList<>();
        }
        if (start.getTime() > end.getTime()) {
            throw new BizException("开始时间不能大于结束时间");
        }

        List<String> result = new ArrayList<String>();
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);

        tempStart.add(Calendar.DAY_OF_YEAR, 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);
        result.add(sdf.format(start));
        while (tempStart.before(tempEnd)) {
            result.add(sdf.format(tempStart.getTime()));
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }
        if (start.getTime() != end.getTime()) {
            result.add(sdf.format(end));
        }
        return result;
    }

    public static ArrayList<String> getDays(int intervals) {
        ArrayList pastDaysList = new ArrayList<>();

        for (int i = 0; i < intervals; i++) {
            pastDaysList.add(getPastDate(i));
        }
        return pastDaysList;
    }

    public static String getWeek(String dateTime) {
        String week = "";

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        try {
            Date date = sdf.parse(dateTime);

            SimpleDateFormat dateFm = new SimpleDateFormat("EEEE", Locale.CHINESE);
            dateFm.setTimeZone(TimeZone.getTimeZone("Etc/GMT-8"));

            week = dateFm.format(date);

            week = week.replaceAll("星期", "周");

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return week;

    }

    public static String getPastDate(int past) {
        Calendar calendar = Calendar.getInstance();

        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + past);

        Date today = calendar.getTime();

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        String result = format.format(today);

        return result;

    }

    public static String getCurrentDate(String dateStr, Integer second) {
        SimpleDateFormat df = new SimpleDateFormat(YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);
        Date date = null;
        try {
            date = df.parse(dateStr);
            date.setTime(date.getTime() + second);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return df.format(date);
    }

    public static String addDateDays(String dateStr, int days) {

        String timeStr = dateStr.split(" ")[1];
        dateStr = dateStr.split(" ")[0];
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat df = new SimpleDateFormat(YEAR_MONTH_DAY_HOUR_MINUTE_SECOND);

        Date date = null;
        try {
            date = sdf.parse(dateStr);
            date = addDateDays(date, days);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (date != null) {
            if (!StringUtil.isEmpty(timeStr)) {
                return df.format(date) + " " + timeStr;
            }
            return df.format(date);
        }
        return null;
    }

 

posted @ 2021-12-09 14:26  怕黑,可是却恋上了夜  阅读(52)  评论(0编辑  收藏  举报