Java工作时间内的日期时间加减法

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;

public class WorkTimeCalculator {
    // 工作上班时间
    private static final LocalTime[] WORKING_HOURS_START = { LocalTime.of(8, 0), LocalTime.of(14, 0),
            LocalTime.of(19, 0) };
    // 工作下班时间
    private static final LocalTime[] WORKING_HOURS_END = { LocalTime.of(12, 0), LocalTime.of(18, 0),
            LocalTime.of(21, 0) };

    // 辅助方法:判断给定时间是否在工作时间之前
    private static boolean isBeforeWorkingHours(LocalTime time, LocalTime startTime) {
        return time.isBefore(startTime);
    }

    // 辅助方法:判断给定时间是否在工作时间之后
    private static boolean isAfterWorkingHours(LocalTime time, LocalTime endTime) {
        return time.isAfter(endTime);
    }

    // 辅助方法:找到给定时间所在的工作时间段索引
    private static int findWorkingPeriodIndex(LocalTime time) {
        for (int i = 0; i < WORKING_HOURS_START.length; i++) {
            if (!isBeforeWorkingHours(time, WORKING_HOURS_START[i])
                    && !isAfterWorkingHours(time, WORKING_HOURS_END[i])) {
                return i;
            }
        }
        return -1;
    }

    // 对给定的时间进行对齐,以找到下一个工作时间段的开始时间
    private static LocalDateTime alignToNearestWorkTime(LocalDateTime time) {
        for (int i = 0; i < WORKING_HOURS_START.length; i++) {
            if (time.toLocalTime().isBefore(WORKING_HOURS_START[i])) {
                return time.toLocalDate().atTime(WORKING_HOURS_START[i]);
            }
        }
        // 如果时间在所有时间段之前,则返回第一个时间段开始时间
        return time.toLocalDate().atTime(WORKING_HOURS_START[0]);
    }

    // 添加工作分钟数的方法
    public static LocalDateTime addWorkingMinutes(LocalDateTime startTime, int minutesToAdd) {
        int workingMinutesAdded = 0;
        // 确保startTime是工作日的某个时间,并调整至最近的工作时间段开始
        if (findWorkingPeriodIndex(startTime.toLocalTime()) == -1) {
            startTime = alignToNearestWorkTime(startTime);
        }
        LocalDateTime currentTime = startTime;

        while (workingMinutesAdded < minutesToAdd) {
            int workingPeriodIndex = findWorkingPeriodIndex(currentTime.toLocalTime());

            // 计算在当前工作时间段内可以添加的分钟数
            long minutesAvailable = ChronoUnit.MINUTES.between(currentTime.toLocalTime(),
                    WORKING_HOURS_END[workingPeriodIndex]);
            int minutesToAddThisPeriod = (int) Math.min(minutesAvailable, minutesToAdd - workingMinutesAdded);

            // 更新时间
            currentTime = currentTime.plusMinutes(minutesToAddThisPeriod);
            workingMinutesAdded += minutesToAddThisPeriod;

            // 如果已经添加了足够的分钟数,则退出循环
            if (workingMinutesAdded >= minutesToAdd) {
                break;
            }

            // 否则,移动到下一个工作时间段的开始
            workingPeriodIndex = (workingPeriodIndex + 1) % WORKING_HOURS_START.length;
            currentTime = currentTime.with(LocalTime.of(WORKING_HOURS_START[workingPeriodIndex].getHour(),
                    WORKING_HOURS_START[workingPeriodIndex].getMinute()));

            // 如果需要跨越到下一个工作日,则增加一天
            if (currentTime.isBefore(startTime)) {
                currentTime = currentTime.plusDays(1);
            }
        }
        return currentTime;
    }

    // 示例方法
    public static void main(String[] args) {
        // 设定开始时间为晚上14:00
        LocalDateTime startTime = LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.of(16, 0));
        // 要增加的分钟数
        int minutesToAdd = 232;
        // 调用方法并打印结果
        LocalDateTime endTime = addWorkingMinutes(startTime, minutesToAdd);
        System.out.println("开始时间: " + startTime);
        System.out.println("增加 " + minutesToAdd + "分钟 (" + 232 / 60 + "小时" + 232 % 60 + "分钟)");
        System.out.println("结束时间: " + endTime);
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。