OA系统的天数该怎样计算

本文最后更新于 2025年1月1日

在开发一些OA系统的过程中,经常能遇到一个问题,就是时长计算,比如请假有请假的时长,出差有出差的时长,有的公司请假只能按照整天或小时为单位请假,这种都比较好处理,只要排除休息日节假日天数或排除下班非工作小时数加午休( 如果有的话😂)小时数直接相减即可,但是如果需求是按照半天为单位,OA系统该怎样计算总时长呢?

以半天为最小单位时,机械的加减有时可能无法和实际情况相符,例如我在OA系统提交休假审批,从1号上午到2号上午为假期,如果直接假定开始的小时都一样直接把日期时间简单相减,那么休假时间就是24小时构成的1天,但是实际上假期的构成是1号上午,1号下午,以及2号上午,按照工时的普遍计算逻辑就是1.5个工作日,OA系统应计算实际休假时长是1.5天,那这种场景下OA系统要怎样计算才准确呢,我把情况分为4种分别处理,分别计算休假一天,两天和三天的情况,进而推导到更长时间

1. 上午开始,上午结束

1天内的情况是0.5天,2天内的是1.5天,3天内是2.5天

2. 上午开始,下午结束

1天内的情况是1天,2天内的是2天,3天内是3天

3. 下午开始,下午结束

1天内的情况是0.5天,2天内的是1.5天,3天内是2.5天

4. 下午开始,上午结束

1天内不会有这种情况,2天内的是1天,3天内是2天

综上,计算的代码就是这样的:

public static void main(String[] args) {
    System.out.println(test(
            LocalDate.parse("2024-12-01"),
            LocalDate.parse("2024-12-03"),
            1,
            1
    ));
}

/**
 * 
 * @param start 开始日期
 * @param end 结束日期
 * @param startPeriod 开始 1上午2下午
 * @param endPeriod 结束 1上午 2下午
 * @return
 */
public static double test(LocalDate start, LocalDate end, int startPeriod, int endPeriod) {
    // 如果开始时间或结束时间为空,则返回 0 天
    if (start == null || end == null) {
        return 0.0; // 确保返回值类型一致
    }

    // 计算两个日期之间的整天数
    double between = (double) java.time.temporal.ChronoUnit.DAYS.between(start, end);

    //天数相减会把涉及的天数算少一天,所以要加回来
    between ++;

    // 根据时间段调整天数
    if (startPeriod == 1) { // 开始是上午
        if (endPeriod == 1) { // 结束是上午
            between =  between - 0.5 ;
        }

    }
    else if (startPeriod == 2) { // 开始是下午
        if (endPeriod == 1) { // 结束是上午
            between = between - 1;
        }
        else if (endPeriod == 2) { // 结束是下午
            between = between - 0.5 ;
        }
    }

    // 返回计算后的天数
    return between;
}

OA系统的天数该怎样计算
https://blog.liuzijian.com/post/oa-system-count-days.html
作者
Liu Zijian
发布于
2024年12月31日
更新于
2025年1月1日
许可协议