You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C++中计算距离下一个允许时间窗口剩余秒数的问题求助

C++中计算距离下一个允许时间窗口剩余秒数的问题求助

大家好,我最近在写一个C++函数时碰到了瓶颈,想请各位大佬帮忙指点一下。这个函数的作用是计算距离下一个允许执行特定操作的时间窗口还剩多少秒。

先跟大家明确下时间窗口的规则:比如我设定的允许时间段是每年的3日到5日,并且在这些日子里,每天只有两个时间段可以操作——6:00到8:00,以及18:00到20:00。不过举个实际例子更清楚:如果输入的时间戳是1681146633(对应Mon Apr 10 2023 17:10:33),我期望输出2967秒,因为这是到当天18:00(下一个窗口的开始时间)的剩余秒数,这说明可能我的时间窗口规则其实是每天都有固定的时段窗口?可能我之前的描述有点混乱,总之核心需求是根据预设的日期区间+每日时间区间,计算当前时间到下一个有效窗口的剩余秒数。

我自己尝试写了代码,但逻辑肯定有问题,没能得到正确结果。下面是我的实现思路和代码:

时间窗口的存储方式

我想用一个二维浮点数数组allowedTime来存储允许的时间区间:

  • 第一行的数值成对出现,每一对代表一个日期区间(开始日和结束日,比如3,5就表示每月3日到5日)
  • 第二行的数值也成对出现,每一对代表一个每日时间区间,用浮点数表示半小时,比如18.5对应18:30

但我数组的定义明显写错了,原代码是这样的:

float allowedTime[18][2] = {
    3,5,   3,   5,  6,  8, 6, 8,  9, 11,   9,  11,12,  2,  12,  2,
    6,8,18.5,20.5,5.5,7.5,19,21,6.5,8.5,17.5,19.5, 7,8.5,16.5,18,
};

现在看这个定义完全不对,18行2列的数组根本装不下这么多元素,应该是2行16列才对,我搞反了维度。

核心函数实现

我用了ESP32的ESP32Time类来处理时间,写了SecondsRemaingTo函数计算剩余秒数,还有一个辅助函数AddTime用来给时间结构体增加秒数:

int SecondsRemaingTo(ESP32Time &rtc,float allowedTime[][2]){
    int currentMonth = rtc.getMonth()+1, currentHour=rtc.getHour(true);
    int arrayx=18,arrayy=2;
    long int Epoch = rtc.getEpoch();
    // 临时时间结构体,用来逐步增加时间
    time_t unixTime = static_cast<time_t>(Epoch);
    struct tm* TempTime = localtime(&unixTime);
    // 这里变量名拼写错了:curruntHour → currentHour
    int currentMon = TempTime->tm_mon + 1, curruntHour = TempTime->tm_hour, currentMin= TempTime->tm_min;
    int secondToNextWindow=0;

    for (int i = 0; i < arrayx; i=i+2)
    {
        // 这里逻辑完全错了!我用当前月份去判断日期区间
        if(currentMon>=allowedTime[i][0] && currentMon<=allowedTime[i+1][0]){
            float minutes;
            // 判断是否要加0.5表示半小时
            if(currentMin>=30){
                minutes = 0.5;
            }else{
                minutes = 0;
            }
            float currentTimeFloat = static_cast<float>(curruntHour)+minutes;
            // 判断当前时间是否在时间区间内
            if(currentTimeFloat>=allowedTime[i][1] && currentTimeFloat<=allowedTime[i+1][1]){
                return secondToNextWindow;
            }else{
                // 每次加30分钟,直到找到窗口
                AddTime(1800, TempTime);
                secondToNextWindow+=1800;
            }
        }
    }
    // 原代码没有默认返回值,会编译报错
    return secondToNextWindow;
}

void AddTime(int seconds, tm* date) {
    if (date == NULL) return;
    date->tm_sec += seconds;
    mktime(date);
}

现在我知道代码里肯定有不少错误,比如把日期区间当成月份判断、数组维度错误、循环逻辑可能没覆盖所有情况,还有没考虑当天没有窗口的话要跳到第二天甚至下个月的窗口。希望各位能帮我找出这些问题,或者给我一些更清晰的实现思路,让这个函数能正确计算出剩余秒数。

备注:内容来源于stack exchange,提问作者Maremma Cane

火山引擎 最新活动