首页 > 编程语言 >java-计算发送时间

java-计算发送时间

时间:2023-04-26 09:58:22浏览次数:27  
标签:00 12 java String 发送 add timeNodeList 计算 Date

package cn.com.fl.service.utils;


import cn.com.doone.tocloud.tools.MyLogUtil;
import cn.com.doone.tocloud.tools.MyLogger;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


public class ComputeSendTimeUtil {

    static MyLogger logger = MyLogUtil.getLogger(ComputeSendTimeUtil.class);

    /**
     * 计算发送时间
     * @param lastSendTime   yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String computeSendTime(String lastSendTime,String rules,List<String> timeNodeList,int rowNum){
        logger.log(MyLogUtil.LOG_INFO,"进入计算发送时间");
        String sendTime = "";
        Date now = new Date();
        // 根据配置获取时间范围 时:分 格式例如(08:00  12:00  14:00  20:00)
        List<String> timeList = new ArrayList<>(Arrays.asList(rules.split("-")));
        String strStartTime1 = timeList.get(0).substring(0,timeList.get(0).lastIndexOf(":"));
        String strEndTime1 = timeList.get(1).substring(0,timeList.get(1).lastIndexOf(":"));
        String strStartTime2 = timeList.get(2).substring(0,timeList.get(2).lastIndexOf(":"));
        String strEndTime2 = timeList.get(3).substring(0,timeList.get(3).lastIndexOf(":"));

        SimpleDateFormat sdfHM = new SimpleDateFormat("HH:mm");
        String nowStr = sdfHM.format(now);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdfYMD = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = sdf.parse(lastSendTime);
            String zeroTimeHMStr = "00:00";
            Date zeroTime = sdfHM.parse(zeroTimeHMStr);
            String nowStrYMD = sdfYMD.format(now);

            //HH:mm格式的当前时间
            Date nowTime  = sdfHM.parse(nowStr);
            //上午时间区间String转Date
            Date startTime1 = sdfHM.parse(strStartTime1);
            Date endTime1  = sdfHM.parse(strEndTime1);
            //下午时间区间String转Date
            Date startTime2 = sdfHM.parse(strStartTime2);
            Date endTime2  = sdfHM.parse(strEndTime2);
            // 最后一条发送时间是否超过当前时间
            if(date.compareTo(now) <= 0){ // 不超过
                logger.log(MyLogUtil.LOG_INFO,"最后一条发送时间("+lastSendTime+")不超过当前时间:");
                // 当前时间是否在规则时间范围内
                if (isEffectiveDate(nowTime, startTime1, endTime1) || isEffectiveDate(nowTime, startTime2, endTime2)) {
                    System.out.println("当前时间在时间段内["+strStartTime1+","+strEndTime1+"]或["+strStartTime2+","+strEndTime2+"]");
                    Date newTime = now;
                    while (true){
                        if(timeNodeList.contains(nowStr)){ // 如果正好在时间节点上
                            // 生成发送时间
                            sendTime = setTime(nowStrYMD,nowStr,rowNum);
                            break;
                        }else{ // 如果不在时间节点上 就加1分钟,再进循环去判断,直到匹配到后跳出循环返回数据
                            newTime = new Date(newTime.getTime() + 60000);
                            Date newTimeHM = sdfHM.parse(sdfHM.format(newTime));
                            if (isEffectiveDate(newTimeHM, startTime1, endTime1) || isEffectiveDate(newTimeHM, startTime2, endTime2)) {
                                nowStr = sdfHM.format(newTime);
                            }else{
                                // 直接生成发送时间(虽然超出了范围一点)
                                nowStr = sdfHM.format(newTime);
                                sendTime = setTime(nowStrYMD,nowStr,rowNum);
                                break;
                            }
                        }
                    }
                } else {
                    System.out.println("当前时间不在时间段内["+strStartTime1+","+strEndTime1+"]或["+strStartTime2+","+strEndTime2+"]");
                    // 判断是否在 zeroTime -  startTime1 (0:00 -  08:00) 区间
                    if(isEffectiveDate(nowTime, zeroTime, startTime1)){
                        // 生成发送时间
                        sendTime = setTime(nowStrYMD,strStartTime1,rowNum);
                    } // 判断是否在 endTime1 -  startTime2 (12:00 -  14:00) 区间
                    else if(isEffectiveDate(nowTime, endTime1, startTime2)){
                        // 生成发送时间
                        sendTime = setTime(nowStrYMD,strStartTime2,rowNum);
                    }else { // 说明时间超过了 endTime2 20:00
                        // 日期加 1 天
                        Date secondDate = dateAddOne(now);
                        String secondDateStr = sdfYMD.format(secondDate);
                        // 生成发送时间
                        sendTime = setTime(secondDateStr,strStartTime1,rowNum);
                    }
                }
            }else{  // 超过
                logger.log(MyLogUtil.LOG_INFO,"最后一条发送时间("+lastSendTime+")超过当前时间:");
                // 获取发送时间分钟数匹配下一个时间节点加上随机数
                Date lastSendTimeDate = sdf.parse(lastSendTime);
                // 先随机加分钟数
                Date afterLastSendTimeDate = new Date(lastSendTimeDate.getTime() + rowNum * 60000);

                String lastSendTimeYMD = sdfYMD.format(lastSendTimeDate);  // 获取日期字符串 yyyy-MM-dd
                String lastSenfTimeHM = sdfHM.format(afterLastSendTimeDate);  // 获取时分字符串 HH:mm
                Date lastSendTimeDateHM = sdfHM.parse(sdfHM.format(sdf.parse(lastSendTime))); // 获取时分 HH:mm
                // 获取的最后时间是否在规则时间范围内
                if (isEffectiveDate(lastSendTimeDateHM, startTime1, endTime1) || isEffectiveDate(lastSendTimeDateHM, startTime2, endTime2)) {
                    System.out.println("最后发送时间在时间段内["+strStartTime1+","+strEndTime1+"]或["+strStartTime2+","+strEndTime2+"]");
                    Date newTime = afterLastSendTimeDate;
                    while (true){
                        if(timeNodeList.contains(lastSenfTimeHM)){ // 如果正好在时间节点上
                            // 生成发送时间
                            sendTime = setTime(lastSendTimeYMD,lastSenfTimeHM,rowNum);
                            break;
                        }else{ // 如果不在时间节点上 就加1分钟,再进循环去判断,直到匹配到后跳出循环返回数据
                            newTime = new Date(newTime.getTime() + 60000);
                            Date newTimeHM = sdfHM.parse(sdfHM.format(newTime));
                            if (isEffectiveDate(newTimeHM, startTime1, endTime1) || isEffectiveDate(newTimeHM, startTime2, endTime2)) {
                                lastSenfTimeHM = sdfHM.format(newTime);
                            }else{
                                // 直接生成发送时间(虽然超出了范围一点)
                                lastSenfTimeHM = sdfHM.format(newTime);
                                sendTime = setTime(lastSendTimeYMD,lastSenfTimeHM,rowNum);
                                break;
                            }
                        }
                    }
                }else{
                    System.out.println("最后发送时间不在时间段内["+strStartTime1+","+strEndTime1+"]或["+strStartTime2+","+strEndTime2+"]");
                    // 判断是否在 zeroTime -  startTime1 (0:00 -  08:00) 区间
                    if(isEffectiveDate(lastSendTimeDateHM, zeroTime, startTime1)){
                        // 生成发送时间
                        sendTime = setTime(lastSendTimeYMD,strStartTime1,rowNum);
                    } // 判断是否在 endTime1 -  startTime2 (12:00 -  14:00) 区间
                    else if(isEffectiveDate(lastSendTimeDateHM, endTime1, startTime2)){
                        // 生成发送时间
                        sendTime = setTime(lastSendTimeYMD,strStartTime2,rowNum);
                    }else { // 说明时间超过了 endTime2 20:00
                        // lastSendTimeYMD 日期加 1 天
                        Date secondDate = dateAddOne(lastSendTimeDate);
                        String secondDateStr = sdfYMD.format(secondDate);
                        // 生成发送时间
                        sendTime = setTime(secondDateStr,strStartTime1,rowNum);
                    }
                }

            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return sendTime;
    }

    /**
     * 生成发送时间
     * @param rq  2022-04-14
     * @param sj  14:00
     * @param rowNum 5
     * @return
     */
    public static String setTime(String rq,String sj,int rowNum){
        logger.log(MyLogUtil.LOG_INFO,"进入生成发送时间:[日期:" + rq + ",时分:" + sj + ",随机数:" +rowNum);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sendTime = "";
        String timeStr = rq + " " + sj + ":00";  // 拼接格式 yyyy-MM-dd HH:mm:ss
        Date timeDate = null;
        try {
            timeDate = sdf.parse(timeStr);
            // 分钟数据加上随机分钟数
            Date afterDate = new Date(timeDate.getTime() + rowNum * 60000);
            sendTime = sdf.format(afterDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return sendTime;
    }

    /**
     * 判断当前时间是否在[startTime, endTime]区间,注意三个参数的时间格式要一致
     * @param nowTime  同格式 (14:34)
     * @param startTime  14:00
     * @param endTime  20:00
     * @return 在时间段内返回true,不在返回false
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        return date.after(begin) && date.before(end);
    }

    /**
     * 日期加+1天
     * @param date
     * @return
     */
    public static Date dateAddOne(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, 1); //把日期往后增加一天,整数  往后推,负数往前移动
        date = calendar.getTime(); //这个时间就是日期往后推一天的结果
        return date;
    }

    /**
     * 时间段相差分钟数
     * @param startTime 开始时间 14:00
     * @param endTime   结束时间 20:00
     * @return
     */
    public static long differMin(String startTime,String endTime){
        long minute = -1;
        SimpleDateFormat sdfHM = new SimpleDateFormat("HH:mm");
        try {
            Date startTimeDate = sdfHM.parse(startTime);
            Date endTimeDate = sdfHM.parse(endTime);
            minute = (endTimeDate.getTime() - startTimeDate.getTime())/1000/60;
            System.out.println(minute);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return minute;
    }

    /**
     * 根据两个时间范围计算每一个发送的时间节点和间隔时间差
     * @param startTimeStr1  早上开始时间 08:00
     * @param endTimeStr1    早上结束时间 12:00
     * @param startTimeStr2  下午开始时间 14:00
     * @param endTimeStr2    下午结束时间 20:00
     * @param count          每天每个员工最多添加个数
     * @return
     */
    public static Map<String,Object>  timeNode (String startTimeStr1, String endTimeStr1, String startTimeStr2, String endTimeStr2, long count){
        logger.log(MyLogUtil.LOG_INFO,"进入计算时间节点");
        Map<String,Object> resultMap = new HashMap<>();
        List<String> timeNodeList = new ArrayList<>();
        long num = 1;
        try {
            SimpleDateFormat sdfHM = new SimpleDateFormat("HH:mm");
            Date startTimeDate1 = sdfHM.parse(startTimeStr1);
            Date endTimeDate1 = sdfHM.parse(endTimeStr1);
            Date startTimeDate2 = sdfHM.parse(startTimeStr2);
            Date endTimeDate2 = sdfHM.parse(endTimeStr2);

            // 计算总分钟数(用时间段相差分钟数)
            long a = differMin(startTimeStr1,endTimeStr1);
            long b = differMin(startTimeStr2,endTimeStr2);
            long min = a + b;
            // 计算时间节点相差分钟数
            num = min/count;
            // 算出第2个时间范围的所有时间节点
            Date nextTimeNodeDate1 = startTimeDate1;
            while (true){
                if(isEffectiveDate(nextTimeNodeDate1,startTimeDate1,endTimeDate1)){
                    String nextTimeNodeStr = sdfHM.format(nextTimeNodeDate1);
                    timeNodeList.add(nextTimeNodeStr);
                    nextTimeNodeDate1 = new Date(nextTimeNodeDate1.getTime() + num * 60000);
                }else{
                    // 如果数组包含最后一个节点就删除掉
                    if(timeNodeList.contains(endTimeStr1)){
                        // 删除最后一个元素 12:00 剩下以下的节点
                        // [08:00, 08:12, 08:24, 08:36, 08:48, 09:00, 09:12, 09:24, 09:36, 09:48, 10:00, 10:12, 10:24, 10:36, 10:48, 11:00, 11:12, 11:24, 11:36, 11:48]
                        timeNodeList.remove(timeNodeList.size()-1);
                    }
                    break;
                }
            }
            // 算出第2个时间范围的所有时间节点
            Date nextTimeNodeDate2 = startTimeDate2;
            while (true){
                if(isEffectiveDate(nextTimeNodeDate2,startTimeDate2,endTimeDate2)){
                    String nextTimeNodeStr = sdfHM.format(nextTimeNodeDate2);
                    timeNodeList.add(nextTimeNodeStr);
                    nextTimeNodeDate2 = new Date(nextTimeNodeDate2.getTime() + num * 60000);
                }else{
                    // 如果数组包含最后一个节点就删除掉
                    if(timeNodeList.contains(endTimeStr2)){
                        // 删除最后一个元素 20:00 剩下以下的节点
                        timeNodeList.remove(timeNodeList.size()-1);
                    }
                    break;
                }
            }
            System.out.println("时间节点:" + timeNodeList);

        } catch (ParseException e) {
            e.printStackTrace();
        }
        resultMap.put("timeNodeList",timeNodeList);
        resultMap.put("num",num);
        return resultMap;
    }



    public static void main(String[] args) {

        String rules = "08:00:00-12:00:00-14:00:00-20:00:00"; // // 做成配置传进来后续
        List<String> timeNodeList = new ArrayList<>(); // 时间节点后续根据以上配置算好传进来
        timeNodeList.add("08:00");timeNodeList.add("08:12");timeNodeList.add("08:24");timeNodeList.add("08:36");timeNodeList.add("08:48");
        timeNodeList.add("09:00");timeNodeList.add("09:12");timeNodeList.add("09:24");timeNodeList.add("09:36");timeNodeList.add("09:48");
        timeNodeList.add("10:00");timeNodeList.add("10:12");timeNodeList.add("10:24");timeNodeList.add("10:36");timeNodeList.add("10:48");
        timeNodeList.add("11:00");timeNodeList.add("11:12");timeNodeList.add("11:24");timeNodeList.add("11:36");timeNodeList.add("11:48");

        timeNodeList.add("14:00");timeNodeList.add("14:12");timeNodeList.add("14:24");timeNodeList.add("14:36");timeNodeList.add("14:48");
        timeNodeList.add("15:00");timeNodeList.add("15:12");timeNodeList.add("15:24");timeNodeList.add("15:36");timeNodeList.add("15:48");
        timeNodeList.add("16:00");timeNodeList.add("16:12");timeNodeList.add("16:24");timeNodeList.add("16:36");timeNodeList.add("16:48");
        timeNodeList.add("17:00");timeNodeList.add("17:12");timeNodeList.add("17:24");timeNodeList.add("17:36");timeNodeList.add("17:48");
        timeNodeList.add("18:00");timeNodeList.add("18:12");timeNodeList.add("18:24");timeNodeList.add("18:36");timeNodeList.add("18:48");
        timeNodeList.add("19:00");timeNodeList.add("19:12");timeNodeList.add("19:24");timeNodeList.add("19:36");timeNodeList.add("19:48");

        int rowNum = 5; // 后续外面根据随机数生成规则传进来
//        String sendTime = computeSendTime("2010-01-01 10:00:00",rules,timeNodeList,7);
//        String sendTime = computeSendTime("2022-04-16 19:59:00",rules,timeNodeList,-4);
//        String sendTime = computeSendTime("2022-04-18 20:15:00",rules,timeNodeList,rowNum);
//        System.out.println(sendTime);

    }
}

 

标签:00,12,java,String,发送,add,timeNodeList,计算,Date
From: https://www.cnblogs.com/bzd1030806032/p/17354728.html

相关文章

  • AI边缘计算智能分析网关灭火器缺失检测与告警的实现过程
    AI智能分析网关基于边缘智能,部署了多种AI深度学习算法,可对接入的多路视频流进行智能检测、智能识别等,包括人脸检测与识别、车辆检测与识别、车牌识别、烟火识别、安全帽识别、区域入侵检测等。今天我们来介绍下关于灭火器缺失检测与告警的实现过程。灭火器缺失检测具体是指,可对......
  • java成员变量在堆_java的基本类型的成员变量在栈还是堆?
    转、:java成员变量在堆_java的基本类型的成员变量在栈还是堆? 先说结论,放在堆中只要是成员变量,所在的类被实例化,不管是不是基础类型都会放在堆中第一个结论就是错的基本数据类型是放在栈中还是放在堆中,这取决于基本类型声明的位置。第一种:在方法中声明的变量,即该变量是......
  • Java基础之String字符串的底层原理,面试常见问题
    前言在之前的两篇文章中,给大家介绍了String字符串及其常用的API方法、常用编码、正则表达式等内容,但这些内容都是停留在”如何用“的阶段,没有涉及到”为什么“的层面。实际上,我们在求职时,面试官很喜欢问我们关于String的一些原理性知识,比如String的不可变性、字符串的内存分配等......
  • java程序jar包打包成exe文件
    说明:将java程序打包成window系统下的exe文件分三步第一步:创建java程序,需要包含一个主方法;第二步:打jar包,通过模块打包。第三步:构建exe,使用软件exe4j将jre,jar包构建成exe文件 案例演示:第一步:创建java程序,需要包含一个主方法; ......
  • JavaScript设计模式
    JavaScript设计模式设计模式概念经过代码设计经验总结之后设计出的一种固定解决问题的方式设计模式作用代码复用保证代码可靠性将编程工程化更易被他人理解设计模式的分类(W3C平台)构造器模式,模块化模式,暴露模块模式,单例模式,中介者模式,原型模式,命令模式,外......
  • 基于Java开发的全文检索、知识图谱、工作流审批机制的知识库
    一、项目介绍一款全源码,可二开,可基于云部署、私有部署的企业级知识库云平台,应用在需要进行常用文档整理、分类、归集、检索的地方,适合知识密集型单位/历史文档丰富的单位,或者大型企业、集团。为什么建立知识库平台?二、项目所用技术springboot+vue+tinyMce+activiti+elastics......
  • java垃圾回收机制(面试)
    1.1堆空间结构Java的自动内存管理主要是针对对象内存的回收和对象内存的分配。同时,Java自动内存管理最核心的功能是堆内存中对象的分配与回收。Java堆是垃圾收集器管理的主要区域,因此也被称作GC堆。Eden区、两个Survivor区S0和S1都属于新生代,中间一层属于老年......
  • 01-计算机系统简介
    01-计算机系统简介计算机系统分为两大类软件和硬件软件分为系统软件和应用软件系统软件:用来管理整个计算机系统语言处理程序;所有的高级语言都要编译成可以在计算机上执行的语言操作系统;服务型程序;像MPI,管理并行程序,管理进程间通信等;数据库管理系统;网络软件应用软件:按......
  • 02-计算机组成
    02-计算机组成冯诺依曼计算机的基本特点由五大部分组成运算器、控制器、存储器、输入设备、输出设备指令和数据以同等地位存于存储器,可按地址寻访指令和数据用二进制表示指令由操作码和地址码组成存储程序以运算器为中心现代计算机硬件框图运算器(ALU-algorithmunit)......
  • 03-计算机的发展
    03-计算机的发展各种语言机器语言面向机器汇编语言面向机器高级语言面向问题FORTRAN科学计算和工程计算PASCAL结构化程序设计C++面向对象Java适应网络环境软件发展的特点开发周期长制作成本昂贵(一个复杂软件4000w行,一人一年开发1w行,需要1000人/年)工资昂贵......