一个完整的DateUtils.java

119 阅读12分钟

我们CTO是个二逼,有洁癖,本来用hutool用的好好的,他非说有漏洞,还把截图给我看,说要我们自己封装一个日期有关的工具类,很“荣幸”这个任务交给了我,没办法,干吧!

image.png

  1. 参考hutool日期工具类实现,并将其DatePattern直接拷贝过来并修修改改
public final class DatePattern {




    /* 一天的开始时间 */
    public static final String BEGIN_TIME_OF_DAY = " 00:00:00";

    /* 一天的结束时间 */
    public static final String END_TIME_OF_DAY = " 23:59:59";

    //-------------------------------------------------------------------------------------------------------------------------------- Normal
    /**
     * 年格式:yyyy
     */
    public static final String NORM_YEAR_PATTERN = "yyyy";
    /**
     * 年月格式:yyyy-MM
     */
    public static final String NORM_MONTH_PATTERN = "yyyy-MM";

    /**
     * 简单年月格式:yyyyMM
     */
    public static final String SIMPLE_MONTH_PATTERN = "yyyyMM";

    /**
     * 标准日期格式:yyyy-MM-dd
     */
    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";

    /**
     * 标准时间格式:HH:mm:ss
     */
    public static final String NORM_TIME_PATTERN = "HH:mm:ss";

    /**
     * 标准日期格式:MM/dd
     */
    public static final String NORM_DAY_PATTERN = "MM/dd";

    /**
     * 标准日期时间格式,精确到分:yyyy-MM-dd HH
     */
    public static final String NORM_DATETIME_HOUR_PATTERN = "yyyy-MM-dd HH";

    /**
     * 标准日期时间格式,精确到分:yyyy-MM-dd HH:mm
     */
    public static final String NORM_DATETIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm";

    /**
     * 标准日期时间格式,精确到分:MM-dd HH:mm
     */
    public static final String NORM_SHORT_PATTERN = "MM-dd HH:mm";

    /**
     * 标准日期时间格式,精确到秒:yyyy-MM-dd HH:mm:ss
     */
    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 标准日期时间格式,精确到毫秒:yyyy-MM-dd HH:mm:ss.SSS
     */
    public static final String NORM_DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";

    /**
     * ISO8601日期时间格式,精确到毫秒:yyyy-MM-dd HH:mm:ss,SSS
     */
    public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";

    /**
     * 标准日期格式:yyyy年
     */
    public static final String CHINESE_YEAR_PATTERN = "yyyy年";

    /**
     * 标准日期格式:yyyy年MM月
     */
    public static final String CHINESE_MONTH_PATTERN = "yyyy年MM月";

    /**
     * 标准日期格式:yyyy年MM月dd日
     */
    public static final String CHINESE_DATE_PATTERN = "yyyy年MM月dd日";

    /**
     * 标准日期格式:MM月dd日
     */
    public static final String CHINESE_DAY_PATTERN = "MM月dd日";

    /**
     * 标准日期格式:yyyy年MM月dd日 HH时mm分ss秒
     */
    public static final String CHINESE_DATE_TIME_PATTERN = "yyyy年MM月dd日HH时mm分ss秒";

    //-------------------------------------------------------------------------------------------------------------------------------- Pure
    /**
     * 标准日期格式:yyyyMMdd
     */
    public static final String PURE_DATE_PATTERN = "yyyyMMdd";

    /**
     * 标准日期格式:HHmmss
     */
    public static final String PURE_TIME_PATTERN = "HHmmss";

    /**
     * 标准日期格式:yyyyMMddHHmmss
     */
    public static final String PURE_DATETIME_PATTERN = "yyyyMMddHHmmss";

    /**
     * 标准日期格式:yyyyMMddHHmmssSSS
     */
    public static final String PURE_DATETIME_MS_PATTERN = "yyyyMMddHHmmssSSS";

    //-------------------------------------------------------------------------------------------------------------------------------- Others
    /**
     * HTTP头中日期时间格式:EEE, dd MMM yyyy HH:mm:ss z
     */
    public static final String HTTP_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";

    /**
     * JDK中日期时间格式:EEE MMM dd HH:mm:ss zzz yyyy
     */
    public static final String JDK_DATETIME_PATTERN = "EEE MMM dd HH:mm:ss zzz yyyy";

    /**
     * ISO8601时间:yyyy-MM-dd'T'HH:mm:ss
     */
    public static final String UTC_SIMPLE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";

    /**
     * ISO8601时间:yyyy-MM-dd'T'HH:mm:ss.SSS
     */
    public static final String UTC_SIMPLE_MS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS";

    /**
     * UTC时间:yyyy-MM-dd'T'HH:mm:ss'Z'
     */
    public static final String UTC_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";

    /**
     * UTC时间:yyyy-MM-dd'T'HH:mm:ssZ
     */
    public static final String UTC_WITH_ZONE_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ssZ";

    /**
     * UTC时间:yyyy-MM-dd'T'HH:mm:ssXXX
     */
    public static final String UTC_WITH_XXX_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ssXXX";

    /**
     * UTC时间:yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
     */
    public static final String UTC_MS_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

    /**
     * UTC时间:yyyy-MM-dd'T'HH:mm:ssZ
     */
    public static final String UTC_MS_WITH_ZONE_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";

    /**
     * UTC时间:yyyy-MM-dd'T'HH:mm:ss.SSSXXX
     */
    public static final String UTC_MS_WITH_XXX_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";


}

2. 经过一个多月的迭代,最终写成了,不依赖任何第三方库



import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;


/**
 * 日期工具类
 *
 * @author 老子
 * @since 1.0.0
 */
public final class DateUtils {

    /**
     * 获取Calendar实例
     *
     * @param date 要设置的日期
     * @return Calendar实例
     */
    private static Calendar getInstance(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    public static String now() {
        return now(DatePattern.NORM_DATETIME_PATTERN);
    }

    public static String now(String pattern) {
        return format(new Date(), pattern);
    }

    /**
     * 创建一个日期
     *
     * @param year  年份
     * @param month 月份
     * @param day   日
     * @return 日期
     */
    public static Date of(int year, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        --month;
        calendar.set(year, month, day);
        return calendar.getTime();
    }

    /**
     * 创建一个日期
     *
     * @param year   年份
     * @param month  月份
     * @param day    日
     * @param hour   时
     * @param minute 分
     * @param second 秒
     * @return 日期
     */
    public static Date of(int year, int month, int day, int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        --month;
        calendar.set(year, month, day, hour, minute, second);
        return calendar.getTime();
    }


    /**
     * 解析日期
     *
     * @param date    要解析的日期
     * @param pattern 格式
     * @return 解析后的日期
     */
    public static Date parse(String date, String pattern) {
        try {
            return new SimpleDateFormat(pattern).parse(date);
        } catch (ParseException e) {
            return null;
        }
    }


    /**
     * 格式化日期
     *
     * @param date    要格式化的日期
     * @param pattern 格式
     * @return 格式化后的日期
     */
    public static String format(Date date, String pattern) {
        try {
            return new SimpleDateFormat(pattern).format(date);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取当前时间的年份数据
     *
     * @return 年份数据
     */
    public static int getYear() {
        return getYear(new Date());
    }

    /**
     * 获取指定时间的年份数据
     *
     * @return 年份数据
     */
    public static int getYear(Date date) {
        return getFields(date, Calendar.YEAR);
    }

    /**
     * 获取当前时间的月份数据
     *
     * @return 月份数据
     */
    public static int getMonth() {
        return getMonth(new Date());
    }

    /**
     * 获取当前时间的月份数据
     *
     * @return 月份数据
     */
    public static int getMonth(Date date) {
        return getFields(date, Calendar.MONTH) + 1;
    }

    /**
     * 获取当前时间的日数据
     *
     * @return 日数据
     */
    public static int getDay() {
        return getDay(new Date());
    }

    /**
     * 获取当前时间的日数据
     *
     * @return 日数据
     */
    public static int getDay(Date date) {
        return getFields(date, Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定时间的指定部分
     *
     * @param date   指定时间
     * @param fields 字段部分
     * @return {@link int}
     * @see java.util.Calendar
     */
    public static int getFields(Date date, int fields) {
        return getInstance(date).get(fields);
    }


    /**
     * 昨天
     *
     * @return {@link Date}
     */
    public static Date yesterday() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }


    /**
     * 昨天,并指定格式
     *
     * @param pattern 日期格式
     * @return {@link String}
     */
    public static String yesterday(String pattern) {
        return format(yesterday(), pattern);
    }


    /**
     * 明天
     *
     * @return {@link Date}
     */
    public static Date tomorrow() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }


    /**
     * 明天,并指定格式
     *
     * @param pattern 日期格式
     * @return {@link String}
     */
    public static String tomorrow(String pattern) {
        return format(tomorrow(), pattern);
    }


    /**
     * 年初
     *
     * @param date 日期
     * @return 指定日期的开始时间
     */
    public static Date beginOfYear(Date date) {
        Calendar calendar = getInstance(date);
        calendar.set(Calendar.MONTH, Calendar.FEBRUARY - 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        return calendar.getTime();
    }

    /**
     * 年末
     *
     * @param date 日期
     * @return 指定日期的结束时间
     */
    public static Date endOfYear(Date date) {
        Calendar calendar = getInstance(date);
        calendar.set(Calendar.MONTH, Calendar.UNDECIMBER - 1);
        calendar.set(Calendar.DAY_OF_MONTH, 31);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);

        return calendar.getTime();
    }


    /**
     * 季初
     *
     * @param date 日期
     * @return 指定日期的开始时间
     */
    public static Date beginOfQuarter(Date date) {
        Calendar calendar = getInstance(date);
        int month = getQuarterInMonth(calendar.get(Calendar.MONTH) + 1, true);
        if (month == -1) {
            return null;
        }
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        return calendar.getTime();
    }


    /**
     * 季末
     *
     * @param date 日期
     * @return 指定日期的开始时间
     */
    public static Date endOfQuarter(Date date) {
        Calendar calendar = getInstance(date);
        int month = getQuarterInMonth(calendar.get(Calendar.MONTH) + 1, false);
        if (month == -1) {
            return null;
        }
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);

        return calendar.getTime();
    }

    /**
     * 获取月份所在的季度开始或者结束的月份
     *
     * @param month 指定月份
     * @param begin 是否获取季度的开始月份
     * @return 开始或者结束的月份
     */
    private static int getQuarterInMonth(int month, boolean begin) {
        int index;

        int[][] months = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};

        if (month >= 1 && month <= 3) {
            index = 0;
        } else if (month >= 4 && month <= 6) {
            index = 1;
        } else if (month >= 7 && month <= 9) {
            index = 2;
        } else if (month >= 10 && month <= 12) {
            index = 3;
        } else {
            return -1;
        }

        if (begin) {
            return months[index][0];
        }
        return months[index][2];
    }


    /**
     * 月初
     *
     * @param date 日期
     * @return 指定日期的开始时间
     */
    public static Date beginOfMonth(Date date) {
        Calendar c = getInstance(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);

        return c.getTime();
    }

    /**
     * 月末
     *
     * @param date 日期
     * @return 指定日期的结束时间
     */
    public static Date endOfMonth(Date date) {
        Calendar c = getInstance(date);
        c.add(Calendar.MONTH, 1);
        c.set(Calendar.DAY_OF_MONTH, 0);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);

        return c.getTime();
    }


    /**
     * 一周的开始时间
     *
     * @param date 日期
     * @return {@link Date}
     */
    public static Date beginOfWeek(Date date) {
        Calendar calendar = getInstance(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        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 日期
     * @return {@link Date}
     */
    public static Date endOfWeek(Date date) {
        Calendar calendar = getInstance(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }


    /**
     * 获取某天的开始时间
     *
     * @param date 日期
     * @return 指定日期的开始时间
     */
    public static Date beginOfDay(Date date) {
        Calendar calendar = getInstance(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        return calendar.getTime();
    }

    /**
     * 获取某天的结束时间
     *
     * @param date 日期
     * @return 指定日期的结束时间
     */
    public static Date endOfDay(Date date) {
        Calendar calendar = getInstance(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }


    /**
     * 偏移日期的年份,生成的偏移日期不影响原日期
     *
     * @param date   需要偏移的日期
     * @param offset 偏移量,正数向未来便宜,负数向过去偏移
     * @return 新的Date对象
     */
    private static Date offsetYear(Date date, int offset) {
        return offset(date, Calendar.YEAR, offset);
    }

    /**
     * 偏移日期的月份,生成的偏移日期不影响原日期
     *
     * @param date   需要偏移的日期
     * @param offset 偏移量,正数向未来便宜,负数向过去偏移
     * @return 新的Date对象
     */
    public static Date offsetMonth(Date date, int offset) {
        return offset(date, Calendar.MONTH, offset);
    }

    /**
     * 偏移日期的日,生成的偏移日期不影响原日期
     *
     * @param date   需要偏移的日期
     * @param offset 偏移量,正数向未来便宜,负数向过去偏移
     * @return 新的Date对象
     */
    public static Date offsetDay(Date date, int offset) {
        return offset(date, Calendar.DAY_OF_MONTH, offset);
    }

    /**
     * 偏移日期的小时,生成的偏移日期不影响原日期
     *
     * @param date   需要偏移的日期
     * @param offset 偏移量,正数向未来便宜,负数向过去偏移
     * @return 新的Date对象
     */
    public static Date offsetHour(Date date, int offset) {
        return offset(date, Calendar.HOUR_OF_DAY, offset);
    }

    /**
     * 偏移日期的分钟,生成的偏移日期不影响原日期
     *
     * @param date   需要偏移的日期
     * @param offset 偏移量,正数向未来便宜,负数向过去偏移
     * @return 新的Date对象
     */
    public static Date offsetMinute(Date date, int offset) {
        return offset(date, Calendar.MINUTE, offset);
    }

    /**
     * 偏移日期的秒,生成的偏移日期不影响原日期
     *
     * @param date   需要偏移的日期
     * @param offset 偏移量,正数向未来便宜,负数向过去偏移
     * @return 新的Date对象
     */
    public static Date offsetSecond(Date date, int offset) {
        return offset(date, Calendar.SECOND, offset);
    }

    /**
     * 偏移日期的毫秒,生成的偏移日期不影响原日期
     *
     * @param date   需要偏移的日期
     * @param offset 偏移量,正数向未来便宜,负数向过去偏移
     * @return 新的Date对象
     */
    public static Date offsetMillisecond(Date date, int offset) {
        return offset(date, Calendar.MILLISECOND, offset);
    }

    /**
     * 偏移日期的指定部分,生成的偏移日期不影响原日期
     *
     * @param date   需要偏移的日期
     * @param field  需要偏移的部分
     * @param offset 偏移量,正数向未来便宜,负数向过去偏移
     * @return 新的Date对象
     */
    public static Date offset(Date date, int field, int offset) {
        Calendar calendar = getInstance(date);
        calendar.add(field, offset);
        return calendar.getTime();
    }


    /**
     * 判断两个日期是否是同一年
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return true|false
     */
    public static boolean isSameYear(Date startDate, Date endDate) {
        Calendar cal1 = getInstance(startDate);
        Calendar cal2 = getInstance(endDate);
        return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
    }


    /**
     * 判断两个日期是否是同一个月
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return true|false
     */
    public static boolean isSameMonth(Date startDate, Date endDate) {

        Calendar cal1 = getInstance(startDate);
        Calendar cal2 = getInstance(endDate);
        return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);

    }


    /**
     * 判断两个日期是否是同一个周
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return true|false
     */
    public static boolean isSameWeek(Date startDate, Date endDate) {

        Calendar cal1 = getInstance(startDate);
        Calendar cal2 = getInstance(endDate);
        cal1.setFirstDayOfWeek(Calendar.MONDAY);
        cal2.setFirstDayOfWeek(Calendar.MONDAY);

        return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(Calendar.WEEK_OF_YEAR);

    }

    /**
     * 判断两个日期是否是同一天
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return true|false
     */
    public static boolean isSameDay(Date startDate, Date endDate) {

        Calendar cal1 = getInstance(startDate);
        Calendar cal2 = getInstance(endDate);
        return cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);

    }


    /**
     * 两个日期相差的年数
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 相差年数的绝对值
     */
    public static long betweenYear(Date startDate, Date endDate) {
        return between(startDate, endDate, ChronoUnit.YEARS);
    }


    /**
     * 两个日期相差的月数
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 相差月数的绝对值
     */
    public static long betweenMonth(Date startDate, Date endDate) {
        return between(startDate, endDate, ChronoUnit.MONTHS);
    }


    /**
     * 两个日期相差的周数
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 相差周数的绝对值
     */
    public static long betweenWeek(Date startDate, Date endDate) {
        return between(startDate, endDate, ChronoUnit.WEEKS);
    }


    /**
     * 两个日期相差的天数
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 相差天数的绝对值
     */
    public static long betweenDay(Date startDate, Date endDate) {
        return between(startDate, endDate, ChronoUnit.DAYS);
    }


    /**
     * 两个日期相差的小时数
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 相差小时数的绝对值
     */
    public static long betweenHour(Date startDate, Date endDate) {
        return between(startDate, endDate, ChronoUnit.HOURS);
    }


    /**
     * 两个日期相差的分钟数
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 相差分钟数的绝对值
     */
    public static long betweenMinute(Date startDate, Date endDate) {
        return between(startDate, endDate, ChronoUnit.MINUTES);
    }


    /**
     * 两个日期相差的秒数
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 相差秒数的绝对值
     */
    public static long betweenSecond(Date startDate, Date endDate) {
        return between(startDate, endDate, ChronoUnit.SECONDS);
    }


    /**
     * 计算两个日期相差部分
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param unit      计算的部分
     * @return 相差数的绝对值
     */
    public static long between(Date startDate, Date endDate, ChronoUnit unit) {
        Calendar cal1 = getInstance(startDate);
        Calendar cal2 = getInstance(endDate);
        LocalDateTime start = LocalDateTime.of(cal1.get(Calendar.YEAR),
                cal1.get(Calendar.MONTH) + 1, cal1.get(Calendar.DAY_OF_MONTH)
                , cal1.get(Calendar.HOUR_OF_DAY), cal1.get(Calendar.MINUTE), cal1.get(Calendar.SECOND));
        LocalDateTime end = LocalDateTime.of(cal2.get(Calendar.YEAR),
                cal2.get(Calendar.MONTH) + 1, cal2.get(Calendar.DAY_OF_MONTH)
                , cal2.get(Calendar.HOUR_OF_DAY), cal2.get(Calendar.MINUTE), cal2.get(Calendar.SECOND));
        return Math.abs(unit.between(start, end));
    }


    /**
     * 拆分指定日期
     * <br/>
     * disassemble("2023-01-01", "2023-01-05", Calendar.DAY_OF_MONTH, "yyyy-MM-dd")
     * <br/>
     * 返回 ["2023-01-01", "2023-01-02", "2023-01-03", "2023-01-04", "2023-01-05"]
     * <br/>
     * disassemble("2023-01-01 12:00", "2023-01-01 12:03", Calendar.MINUTE, "yyyy-MM-dd HH:mm")
     * <br/>
     * 返回 ["2023-01-01 12:00", "2023-01-01 12:01", "2023-01-01 12:02", "2023-01-01 12:03"]
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param field     指定单位 {@link Calendar}
     *                  有效值:Calendar.YEAR,Calendar.MONTH,Calendar.WEEK_OF_MONTH,
     *                  Calendar.DAY_OF_MONTH,Calendar.WEEK_OF_YEAR,Calendar.HOUR,
     *                  Calendar.HOUR_OF_DAY,Calendar.MINUTE,Calendar.SECOND
     * @param pattern   指定格式
     * @return List<String>
     * @see Calendar
     */
    public static List<String> disassemble(String startDate, String endDate, int field, String pattern) {
        return disassemble(parse(startDate, pattern), parse(endDate, pattern), field, pattern);
    }

    /**
     * 拆分指定日期
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param field     指定单位 {@link Calendar}
     *                  有效值:Calendar.YEAR,Calendar.MONTH,Calendar.WEEK_OF_MONTH,
     *                  Calendar.DAY_OF_MONTH,Calendar.WEEK_OF_YEAR,Calendar.HOUR,
     *                  Calendar.HOUR_OF_DAY,Calendar.MINUTE,Calendar.SECOND
     * @param pattern   指定格式
     * @return List<String>
     * @see java.util.Calendar
     */
    public static List<String> disassemble(Date startDate, Date endDate, int field, String pattern) {

        List<String> result = new ArrayList<>();

        List<Date> list = disassemble(startDate, endDate, field);
        list.forEach(t -> result.add(format(t, pattern)));
        return result;
    }


    /**
     * 拆分指定日期
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param field     指定单位 {@link Calendar}
     *                  有效值:Calendar.YEAR,Calendar.MONTH,Calendar.WEEK_OF_MONTH,
     *                  Calendar.DAY_OF_MONTH,Calendar.WEEK_OF_YEAR,Calendar.HOUR,
     *                  Calendar.HOUR_OF_DAY,Calendar.MINUTE,Calendar.SECOND
     * @return List<Date>
     */
    public static List<Date> disassemble(Date startDate, Date endDate, int field) {

        // 结束日期必须在开始日期之前
        if (endDate.before(startDate)) {
            return Collections.emptyList();
        }

        List<Date> result = new ArrayList<>();
        result.add(startDate);

        int i = 1;

        switch (field) {
            case Calendar.YEAR:
                if (isSameYear(startDate, endDate)) {
                    return result;
                }
                return whileTrue(startDate, endDate, field, ChronoUnit.YEARS);
            case Calendar.MONTH:
                if (isSameMonth(startDate, endDate)) {
                    return result;
                }
                return whileTrue(startDate, endDate, field, ChronoUnit.MONTHS);
            case Calendar.WEEK_OF_YEAR:
            case Calendar.WEEK_OF_MONTH:
                if (isSameWeek(startDate, endDate)) {
                    return result;
                }
                while (true) {
                    Date next = offset(startDate, field, i++);
                    if (endDate.before(next)) {
                        return result;
                    }
                    result.add(next);
                    if (betweenWeek(next, endDate) == 0) {
                        if (isSameDay(next, endDate)) {
                            return result;
                        }
                        result.add(endDate);
                        return result;
                    }
                }
            case Calendar.DAY_OF_MONTH:
                if (isSameDay(startDate, endDate)) {
                    return result;
                }
                return whileTrue(startDate, endDate, field, ChronoUnit.DAYS);
            case Calendar.HOUR:
            case Calendar.HOUR_OF_DAY:
                return whileTrue(startDate, endDate, field, ChronoUnit.HOURS);
            case Calendar.MINUTE:
                return whileTrue(startDate, endDate, field, ChronoUnit.MINUTES);
            case Calendar.SECOND:
                return whileTrue(startDate, endDate, field, ChronoUnit.SECONDS);
            default:
                break;
        }
        return result;

    }

    /**
     * 实现开始时间到结束时间的具体拆分逻辑
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @param field     拆分的字段
     * @param unit      单位
     * @return 拆分的结果
     */
    private static List<Date> whileTrue(Date startDate, Date endDate, int field, ChronoUnit unit) {

        List<Date> result = new ArrayList<>();
        result.add(startDate);
        int i = 1;
        while (true) {
            Date next = offset(startDate, field, i++);
            if (endDate.before(next)) {
                return result;
            }
            result.add(next);
            if (between(next, endDate, unit) == 0) {
                return result;
            }
        }
    }
}

后面还要写其他工具类,唉