All Downloads are FREE. Search and download functionalities are using the official Maven repository.

matrix.boot.common.utils.DateUtil Maven / Gradle / Ivy

There is a newer version: 2.1.11
Show newest version
package matrix.boot.common.utils;

import matrix.boot.common.exception.ServiceException;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期工具
 *
 * @author wangcheng
 * 2021/8/11
 **/
public class DateUtil {

    /**
     * 天
     */
    public static final String DATE = "date";

    /**
     * 周
     */
    public static final String WEEK = "week";

    /**
     * 月
     */
    public static final String MONTH = "month";

    /**
     * 年
     */
    public static final String YEAR = "year";

    /**
     * 年格式(yyyy)
     */
    public static final String YEAR_FORMATTER = "yyyy";

    /**
     * 年格式(yy)
     */
    public static final String SHORT_YEAR_FORMATTER = "yy";

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

    /**
     * 日期格式(yyyy-MM-dd)
     */
    public static final String SIMPLE_FORMATTER = "yyyy-MM-dd";

    /**
     * 日期格式(yyyy-MM-dd HH:mm:ss)
     */
    public static final String STANDARD_FORMATTER = "yyyy-MM-dd HH:mm:ss";

    /**
     * 获取当前时间
     *
     * @return 当前时间
     */
    public static LocalDateTime getNow() {
        return LocalDateTime.now();
    }

    /**
     * 时间转换
     *
     * @param localDateTime 时间
     * @return 转换后时间
     */
    public static Date convertDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 时间转换
     *
     * @param date 时间
     * @return 转换后时间
     */
    public static LocalDateTime convertLocalDateTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * 获取当前时间
     *
     * @return 当前时间
     */
    public static Date getNowDate() {
        return Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取当月一共多少天
     *
     * @return 当月一共多少天
     */
    public static Integer getMonthDays(Date date) {
        Date lastDate = getMonthLastDay(date);
        return Integer.parseInt(format(lastDate, "dd"));
    }

    /**
     * 日期格式化
     *
     * @param date   日期
     * @param format 格式表达式
     * @return 格式化后的日期
     */
    public static String format(Date date, String format) {
        return DateFormatUtils.format(date, format);
    }

    /**
     * 日期解析
     *
     * @param format 格式表达式
     * @param date   日期字符串
     * @return 日期
     */
    public static Date parse(String format, String date) {
        try {
            return DateUtils.parseDate(date, format);
        } catch (Exception e) {
            throw new ServiceException("data format error", e);
        }
    }

    /**
     * 重置时分秒
     *
     * @param date 时间
     * @return 时间
     */
    public static Date resetHMS(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        resetHMS(calendar);
        return calendar.getTime();
    }

    /**
     * 获取本月第一天的日期
     *
     * @param date 日期
     * @return 本月第一天的日期
     */
    public static Date getMonthFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, 1);
        resetHMS(calendar);
        return calendar.getTime();
    }

    /**
     * 获取本月最后一天的日期
     *
     * @param date 日期
     * @return 本月最后一天的日期
     */
    public static Date getMonthLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DATE, 1);
        resetHMS(calendar);
        calendar.add(Calendar.DATE, -1);
        return calendar.getTime();
    }

    /**
     * 获取本年第一天的日期
     *
     * @param date 日期
     * @return 本年第一天的日期
     */
    public static Date getYearFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        resetHMS(calendar);
        return calendar.getTime();
    }

    /**
     * 获取本年最后一天的日期
     *
     * @param date 日期
     * @return 本年最后一天的日期
     */
    public static Date getYearLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, 1);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        resetHMS(calendar);
        calendar.add(Calendar.DATE, -1);
        return calendar.getTime();
    }

    /**
     * 获取年周,按天算周,解决跨年问题
     *
     * @param date 时间
     * @return 多少周
     */
    public static Integer getWeekOfYear(Date date) {
        return (int) Math.ceil((getDayOfYear(date) - getDayOfWeek(date) + 1) * 1.0 / 7) + 1;
    }

    /**
     * 获取天
     *
     * @param date 时间
     * @return 哪天
     */
    public static Integer getDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

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

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

    /**
     * 获取每周的第一天
     *
     * @param date 日期
     * @return 第一天
     */
    public static Date getWeekFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        resetHMS(calendar);
        return calendar.getTime();
    }

    /**
     * 获取每周的最后一天
     *
     * @param date 日期
     * @return 最后一天
     */
    public static Date getWeekLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        resetHMS(calendar);
        return calendar.getTime();
    }

    /**
     * 获取之后的日期(负数代表之前的)
     *
     * @param date 日期(week类型,一定是当前时间所在周的第一天)
     * @param type day month week year
     * @param add  数值
     * @return 处理后的日期
     */
    public static Date getAfterDate(Date date, String type, int add) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (DATE.equals(type)) {
            int day = calendar.get(Calendar.DATE);
            calendar.set(Calendar.DATE, day + add);
        } else if (WEEK.equals(type)) {
            int day = calendar.get(Calendar.DATE);
            calendar.set(Calendar.DATE, day + (add * 7));
        } else if (MONTH.equals(type)) {
            int month = calendar.get(Calendar.MONTH);
            calendar.set(Calendar.MONTH, month + add);
        } else if (YEAR.equals(type)) {
            int year = calendar.get(Calendar.YEAR);
            calendar.set(Calendar.YEAR, year + add);
        }
        return calendar.getTime();
    }

    /**
     * 获取周、日
     *
     * @param date 日期
     * @return 时间在一周的第几天
     */
    public static Integer getDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        int day = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        return day == 0 ? 7 : day;
    }

    /**
     * 获取年日
     *
     * @param date 日期
     * @return 年日
     */
    public static Integer getDayOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_YEAR);
    }

    /**
     * 时分秒设置成 00:00:00
     *
     * @param calendar 日历
     */
    private static void resetHMS(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    /**
     * 获取当前时间占当前月的时间比例
     *
     * @param currentDate 当前时间
     * @return 比例
     */
    public static BigDecimal monthRatio(Date currentDate) {
        Integer days = getMonthDays(currentDate);
        Integer currentDay = getDate(currentDate);
        return BigDecimal.valueOf(currentDay).divide(new BigDecimal(days), 2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 组装年月参数,根据开始时间和结束时间
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return yyyy-MM的列表
     */
    public static List packageMonth(String startTime, String endTime) {
        List monthList = new ArrayList<>();
        Date startDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startTime);
        Date endDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endTime);
        while (startDate.getTime() <= endDate.getTime()) {
            monthList.add(DateUtil.format(startDate, YM_FORMATTER));
            startDate = DateUtil.getAfterDate(startDate, DateUtil.MONTH, 1);
        }
        return monthList;
    }

    /**
     * 组装周数据,根据开始时间和结束时间
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return yyW第几周
     */
    public static List packageWeek(String startTime, String endTime) {
        List weekList = new ArrayList<>();
        Date startDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startTime);
        Date endDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endTime);
        while (startDate.getTime() <= endDate.getTime()) {
            weekList.add(DateUtil.format(startDate, SHORT_YEAR_FORMATTER) + "W" + getWeekOfYear(startDate));
            startDate = DateUtil.getAfterDate(startDate, DateUtil.WEEK, 1);
        }
        return weekList;
    }

    /**
     * 组装天参数,根据开始时间和结束时间
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return yyyy-MM-dd列表
     */
    public static List packageDay(String startTime, String endTime) {
        List dayList = new ArrayList<>();
        Date startDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startTime);
        Date endDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endTime);
        while (startDate.getTime() <= endDate.getTime()) {
            dayList.add(DateUtil.format(startDate, SIMPLE_FORMATTER));
            startDate = DateUtil.getAfterDate(startDate, DateUtil.DATE, 1);
        }
        return dayList;
    }

    /**
     * 计算两个时间相差得年份
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 两个时间相差的月份
     */
    public static int calcYear(String startTime, String endTime) {
        Date startDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startTime);
        Date endDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endTime);
        int year = 0;
        while (startDate.getTime() <= endDate.getTime()) {
            year++;
            startDate = DateUtil.getAfterDate(startDate, DateUtil.YEAR, 1);
        }
        return year;
    }

    /**
     * 计算两个时间相差的月份,忽略天
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 两个时间相差的月份
     */
    public static int calcMonth(String startTime, String endTime) {
        Date startDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startTime);
        Date endDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endTime);
        int month = 0;
        while (startDate.getTime() <= endDate.getTime()) {
            month++;
            startDate = DateUtil.getAfterDate(startDate, DateUtil.MONTH, 1);
        }
        return month;
    }

    /**
     * 计算两个时间相差的周数
     *
     * @param startTime 开始时间(当前时间所在周的第一天)
     * @param endTime   结束时间
     * @return 两个时间相差的周数
     */
    public static int calcWeek(String startTime, String endTime) {
        Date startDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startTime);
        Date endDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endTime);
        return (int) Math.floor((endDate.getTime() - startDate.getTime()) * 1.0 / 1000 / 60 / 60 / 24 / 7) + 1;
    }

    /**
     * 计算两个时间相差的天数
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 两个时间相差的天数
     */
    public static int calcDay(String startTime, String endTime) {
        Date startDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startTime);
        Date endDate = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endTime);
        return (int) ((endDate.getTime() - startDate.getTime()) / 1000 / 60 / 60 / 24) + 1;
    }

    /**
     * 获取年中有多少天
     *
     * @param date 时间
     * @return 天
     */
    public static int getYearDays(Date date) {
        int year = getYear(date);
        return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 366 : 365;
    }

    /**
     * 同比=年环比处理(按天算)
     *
     * @param startDate 开始时间(yyyy-MM-dd)
     * @param endDate   结束时间(yyyy-MM-dd)
     * @return [开始时间, 结束时间]
     */
    public static List parseMomForYear(String startDate, String endDate) {
        int calcYear = calcYear(startDate, endDate);
        double errorRatio = 0.0d;
        Date startTime = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startDate);
        Date endTime = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endDate);
        Date actualEndTime = DateUtil.getAfterDate(DateUtil.getAfterDate(startTime, DateUtil.YEAR, calcYear), DateUtil.DATE, -1);
        if (endTime.getTime() < actualEndTime.getTime()) {
            String actualEndDate = DateUtil.format(actualEndTime, DateUtil.SIMPLE_FORMATTER);
            int calcDate = calcDay(endDate, actualEndDate) - 1;
            int yearDays = getYearDays(endTime);
            errorRatio = 1 - (calcDate * 1.0 / yearDays);
        }
        Date newStartTime = DateUtil.getAfterDate(startTime, DateUtil.YEAR, -calcYear);
        Date newEndTime = DateUtil.getAfterDate(newStartTime, DateUtil.YEAR, errorRatio <= 0 ? calcYear : (calcYear - 1));
        if (errorRatio > 0) {
            int days = (int) Math.round(getYearDays(newEndTime) * errorRatio);
            newEndTime = DateUtil.getAfterDate(newEndTime, DateUtil.DATE, days);
        }
        newEndTime = DateUtil.getAfterDate(newEndTime, DateUtil.DATE, -1);
        List result = new ArrayList<>();
        result.add(DateUtil.format(newStartTime, DateUtil.SIMPLE_FORMATTER));
        result.add(DateUtil.format(newEndTime, DateUtil.SIMPLE_FORMATTER));
        return result;
    }


    /**
     * 月环比处理(按天算)
     *
     * @param startDate 开始时间(yyyy-MM-dd)
     * @param endDate   结束时间(yyyy-MM-dd)
     * @return [开始时间, 结束时间]
     */
    public static List parseMomForMonth(String startDate, String endDate) {
        int calcMonth = calcMonth(startDate, endDate);
        double errorRatio = 0.0d;
        Date startTime = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startDate);
        Date endTime = DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endDate);
        Date actualEndTime = DateUtil.getAfterDate(DateUtil.getAfterDate(startTime, DateUtil.MONTH, calcMonth), DateUtil.DATE, -1);
        if (endTime.getTime() < actualEndTime.getTime()) {
            String actualEndDate = DateUtil.format(actualEndTime, DateUtil.SIMPLE_FORMATTER);
            int calcDate = calcDay(endDate, actualEndDate) - 1;
            int monthDays = getMonthDays(endTime);
            errorRatio = 1 - (calcDate * 1.0 / monthDays);
        }
        Date newStartTime = DateUtil.getAfterDate(startTime, DateUtil.MONTH, -calcMonth);
        Date newEndTime = DateUtil.getAfterDate(newStartTime, DateUtil.MONTH, errorRatio <= 0 ? calcMonth : (calcMonth - 1));
        if (errorRatio > 0) {
            int days = (int) Math.round(getMonthDays(newEndTime) * errorRatio);
            newEndTime = DateUtil.getAfterDate(newEndTime, DateUtil.DATE, days);
        }
        newEndTime = DateUtil.getAfterDate(newEndTime, DateUtil.DATE, -1);
        List result = new ArrayList<>();
        result.add(DateUtil.format(newStartTime, DateUtil.SIMPLE_FORMATTER));
        result.add(DateUtil.format(newEndTime, DateUtil.SIMPLE_FORMATTER));
        return result;
    }

    /**
     * 天环比处理(按天算)
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return [开始时间, 结束时间]
     */
    public static List parseMomForDate(String startDate, String endDate) {
        int calcDate = DateUtil.calcDay(startDate, endDate);
        Date newStartTime = DateUtil.getAfterDate(DateUtil.parse(DateUtil.SIMPLE_FORMATTER, startDate), DateUtil.DATE, -calcDate);
        Date newEndTime = DateUtil.getAfterDate(DateUtil.parse(DateUtil.SIMPLE_FORMATTER, endDate), DateUtil.DATE, -calcDate);
        List result = new ArrayList<>();
        result.add(DateUtil.format(newStartTime, DateUtil.SIMPLE_FORMATTER));
        result.add(DateUtil.format(newEndTime, DateUtil.SIMPLE_FORMATTER));
        return result;
    }

    /**
     * 获取原始时间
     *
     * @return 1970...
     */
    public static Date getOriginalDate() {
        Date date = getNowDate();
        date.setTime(0L);
        return date;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy