DateUtil.java 13.4 KB
package com.show.util;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class DateUtil {

    public static Long dateDiff(String startDate, String endDate, String format) {
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);

        // 将字符串日期转换为LocalDate对象
        LocalDate date1 = LocalDate.parse(startDate, formatter);
        LocalDate date2 = LocalDate.parse(endDate, formatter);

        // 计算日期差
        return ChronoUnit.DAYS.between(date1, date2);
    }

    /**
     * 获取两个日期之间的所有日期(包括开始日期和结束日期)
     *
     * @return 日期列表
     */
    public static List<String> getDatesBetween(String startDateStr, String endDateStr) {

        List<String> dates = new ArrayList<>();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        // 解析字符串为 LocalDate 对象
        LocalDate startDate = LocalDate.parse(startDateStr, formatter);
        LocalDate endDate = LocalDate.parse(endDateStr, formatter);

        // 使用循环遍历日期范围
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            dates.add(currentDate.format(formatter));
            currentDate = currentDate.plusDays(1); // 增加一天
        }

        return dates;
    }

    /**
     * 获取两个日期之间的所有日期(包括开始日期和结束日期)
     *
     * @return 日期列表
     */
    public static List<String> getDatesBetweenUtilNow(String startDateStr, String endDateStr) {

        List<String> dates = new ArrayList<>();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        // 解析字符串为 LocalDate 对象
        LocalDate startDate = LocalDate.parse(startDateStr, formatter);
        LocalDate endDate = LocalDate.parse(endDateStr, formatter);
        if (!endDate.isAfter(LocalDate.now())) {
            // 使用循环遍历日期范围
            LocalDate currentDate = startDate;
            while (!currentDate.isAfter(endDate)) {
                dates.add(currentDate.format(formatter));
                currentDate = currentDate.plusDays(1); // 增加一天
            }
        } else {
            // 使用循环遍历日期范围
            LocalDate currentDate = startDate;
            while (!currentDate.isAfter(LocalDate.now())) {
                dates.add(currentDate.format(formatter));
                currentDate = currentDate.plusDays(1); // 增加一天
            }
        }
        return dates;
    }

    public static String dayOfWeek() {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 获取星期几
        DayOfWeek dayOfWeek = today.getDayOfWeek();
        // 转换为中文星期几
        return getChineseDayOfWeek(dayOfWeek);
    }

    public static String getChineseDayOfWeek(DayOfWeek dayOfWeek) {
        switch (dayOfWeek) {
            case MONDAY:
                return "星期一";
            case TUESDAY:
                return "星期二";
            case WEDNESDAY:
                return "星期三";
            case THURSDAY:
                return "星期四";
            case FRIDAY:
                return "星期五";
            case SATURDAY:
                return "星期六";
            case SUNDAY:
                return "星期天";
            default:
                return "未知";
        }
    }

    public static Long calculateTimeDifference(String startTimeStr, String endTimeStr) {
        // 定义时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateFormatUtil.FMT_sdf_HHmm);

        // 将字符串解析为 LocalTime 对象
        LocalTime startTime = LocalTime.parse(startTimeStr, formatter);
        LocalTime endTime = LocalTime.parse(endTimeStr, formatter);

        // 计算时间差
        Duration duration = Duration.between(startTime, endTime);

        // 获取时间差的总秒数
        return Math.abs(duration.getSeconds());
    }

    /**
     * 查看某天是否在某个区间内
     */
    public static boolean dateBetweenOrNot(Date date, Date startDate, Date endDate) {

        try {
            // 判断日期是否在范围内
            return !date.before(startDate) && !date.after(endDate);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 查看某天是否在某个区间内  是的话true  不是的话 false
     */
    public static boolean dateBeforeAfter(String date, String compareDate, String formatter) {

        try {
            Date parse = DateFormatUtil.parse(date, formatter);
            Date parse2 = DateFormatUtil.parse(compareDate, formatter);
            // 判断日期早晚
            return parse.before(parse2);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static String dateToMonth(Integer dayCnt) {
        // 进行除法运算,并指定保留1位小数,使用四舍五入模式
        return new BigDecimal(dayCnt).divide(new BigDecimal(30), 1, RoundingMode.HALF_UP).toString();
    }

    /**
     * 计算时间差
     */
    /**
     * 计算两个时间字符串相差的小时数,保留一位小数
     *
     * @param timeStr1 第一个时间字符串
     * @param timeStr2 第二个时间字符串
     * @return 两个时间相差的小时数(绝对值)
     * @throws ParseException 时间格式解析异常
     *                        取最小值
     */
    public static String calculateHourDifference(String timeStr1, String timeStr2, String cumulativeTime) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(DateFormatUtil.FMT_sdf14_L24);
            Date date1 = sdf.parse(timeStr1);
            Date date2 = sdf.parse(timeStr2);

            // 计算毫秒差的绝对值
            long diffInMillies = Math.abs(date2.getTime() - date1.getTime());

            // 转换为小时(1小时 = 3600000毫秒)
            double diffInHours = diffInMillies / 3600000.0;

            // 使用DecimalFormat保留一位小数
            DecimalFormat df = new DecimalFormat("#.0");
            df.setRoundingMode(RoundingMode.HALF_UP); // 四舍五入

            double num1 = Double.parseDouble(df.format(diffInHours));
            // 将字符串转换为double
            double num2 = Double.parseDouble(cumulativeTime);

            // 取最小值
            double minValue = Math.min(num1, num2);

            // 结果可以保持为数值类型,也可以转回字符串
            return String.valueOf(minValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String currentTime() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        // 获取当前时间并格式化为字符串
        return sdf.format(new Date());
    }

    /**
     * 时间烦我内 日期的时分秒在某个区间
     *
     * @param targetTimeStr
     * @param startTimeStr
     * @param endTimeStr
     * @return
     */
    public static Boolean betweenDateHour(String targetTimeStr, String startTimeStr, String endTimeStr) {

        // 定义时间格式器
        DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern(DateFormatUtil.FMT_sdf14_L24);
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");

        // 解析目标时间为LocalDateTime
        LocalDateTime targetDateTime = LocalDateTime.parse(targetTimeStr, fullFormatter);
        // 提取时间部分
        LocalTime targetTime = targetDateTime.toLocalTime();

        // 解析时间范围
        LocalTime startTime = LocalTime.parse(startTimeStr, timeFormatter);
        LocalTime endTime = LocalTime.parse(endTimeStr, timeFormatter);

        // 判断是否在范围内(包含边界)
        return !targetTime.isBefore(startTime) && !targetTime.isAfter(endTime);
    }

    /**
     * 时间烦我内 日期的时分秒在某个区间
     *
     * @param targetTimeStr
     * @param startTimeStr
     * @param endTimeStr
     * @return
     */
    public static Boolean betweenDate(String targetTimeStr, String startTimeStr, String endTimeStr) {
        // 定义日期时间格式器
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        // 解析时间字符串为LocalDateTime对象
        LocalDateTime targetTime = LocalDateTime.parse(targetTimeStr, dateTimeFormatter);

        // 解析开始日期和结束日期为LocalDate对象
        LocalDate startDate = LocalDate.parse(startTimeStr, dateFormatter);
        LocalDate endDate = LocalDate.parse(endTimeStr, dateFormatter);

        // 将开始日期转换为当天的起始时间(00:00:00)
        LocalDateTime startDateTime = startDate.atStartOfDay();
        // 将结束日期转换为第二天的起始时间(00:00:00),这样包含整个结束日
        LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay();

        // 判断目标时间是否在范围内
        return targetTime.isAfter(startDateTime) && targetTime.isBefore(endDateTime);

    }

    public static String localToString(LocalDateTime localDateTime){
        return localDateTime.toString().replace("T"," ");
    }

    // 定义日期格式
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    /**
     * 计算两个日期之间的工作日天数(排除周六和周日)
     * @param startDateStr 开始日期字符串,格式为"yyyy/MM/dd"
     * @param endDateStr 结束日期字符串,格式为"yyyy/MM/dd"
     * @return 工作日天数
     */
    public static Integer calculateWorkdays(String startDateStr, String endDateStr) {
        // 解析日期字符串为LocalDate对象
        LocalDate startDate = LocalDate.parse(startDateStr, formatter);
        LocalDate endDate = LocalDate.parse(endDateStr, formatter);

        // 确保开始日期不晚于结束日期
        if (startDate.isAfter(endDate)) {
            LocalDate temp = startDate;
            startDate = endDate;
            endDate = temp;
        }

        long totalDays = ChronoUnit.DAYS.between(startDate, endDate) + 1; // 包含起止日期
        int weekends = 0;

        // 遍历每一天,统计周末天数
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            int dayOfWeek = currentDate.getDayOfWeek().getValue();
            // 6是周六,7是周日
            if (dayOfWeek == 6 || dayOfWeek == 7) {
                weekends++;
            }
            currentDate = currentDate.plusDays(1);
        }

        // 工作日 = 总天数 - 周末天数
        return Integer.valueOf((int) totalDays) - weekends;
    }

    /**
     * 计算指定年份对应的学年开始时间和结束时间,返回格式化字符串数组
     * 学年定义为: 当年9月1日 00:00:00 至 次年8月31日 23:59:59
     *
     * @param year 学年的年份,例如2025表示2025学年
     * @return 返回一个包含两个字符串的数组,第一个是开始时间,第二个是结束时间
     *         格式为: yyyy/MM/dd HH:mm:ss
     */
    public static String[] getSchoolYearTimeAsString(int year,int diff) {
        // 定义日期时间格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

        // 学年开始时间:当年9月1日 00:00:00
        LocalDateTime startTime = LocalDateTime.of(year, 9, 1, 0, 0, 0);

        // 学年结束时间:次年8月31日 23:59:59
        LocalDateTime endTime = LocalDateTime.of(year + diff, 8, 31, 23, 59, 59);

        // 格式化并返回字符串数组
        return new String[]{
                startTime.format(formatter),
                endTime.format(formatter)
        };
    }

    /**
     * 检查两个时间字符串的间隔是否超过300秒
     * @param time1 第一个时间字符串
     * @return 如果间隔超过300秒返回true,否则返回false
     * @throws ParseException 时间格式解析错误
     */
    public static boolean isOver300Seconds(String time1) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

        // 解析时间字符串为Date对象
        Date date1 = sdf.parse(time1);

        // 计算两个时间的毫秒差
        long timeDiffMs = Math.abs(date1.getTime() - new Date().getTime());

        // 转换为秒并判断是否超过300秒
        long timeDiffSeconds = timeDiffMs / 1000;
        return timeDiffSeconds >= 300;
    }

    public static Integer currentYear(){
        return Year.now().getValue();
    }

    public static void main(String[] args) {
        // 示例:计算2025学年的时间范围
        int year = 2025;
        String[] schoolYearTimes = getSchoolYearTimeAsString(year,2);

        System.out.println(year + "学年开始时间: " + schoolYearTimes[0]);
        System.out.println(year + "学年结束时间: " + schoolYearTimes[1]);
    }
}