惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
WordPress大学
WordPress大学
MyScale Blog
MyScale Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
The Blog of Author Tim Ferriss
U
Unit 42
罗磊的独立博客
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
The Cloudflare Blog
aimingoo的专栏
aimingoo的专栏
Vercel News
Vercel News
N
Netflix TechBlog - Medium
H
Hackread – Cybersecurity News, Data Breaches, AI and More
云风的 BLOG
云风的 BLOG
Hugging Face - Blog
Hugging Face - Blog
大猫的无限游戏
大猫的无限游戏
F
Fortinet All Blogs
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
博客园 - 【当耐特】
H
Help Net Security
The GitHub Blog
The GitHub Blog

Liu Zijian's Blog | 一个技术博客

使用Certbot自动续签HTTPS证书 使用Filebeat采集Nginx日志到ES Python的协程 Python中的异常 Python中的类和对象 Python的函数 Python的数据结构,推导式、迭代器和生成器 Spring AI集成多模态模型 LangChain4j多模态 LangChain Tools工具使用 Python中的模块和包 Python全局环境和虚拟环境(venv) LangChain Prompt提示词工程 LangChain4j Tools工具使用 基于Dify搭建AI智能体应用 LangChain4j RAG检索增强生成 Spring AI实现MCP Server Spring AI集成MCP Client LangChain4j Prompt提示词工程 Spring AI使用知识库增强对话功能 Spring AI实现一个智能客服 Spring AI实现一个简单的对话机器人 实现MinIO数据的每日备份 自己实现一个DNS服务 简单理解AI智能体 大模型和大模型应用 LangChain开篇 LangChain4j开篇 一个解析Excel2007的POI工具类 DataPermissionInterceptor源码解读
OA系统的天数该怎样计算
Liu Zijian · 2024-12-31 · via Liu Zijian's Blog | 一个技术博客

在开发一些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;
}

一些场景下,为了小数计算更加精确,可以使用java.math.BigDecimal进行计算