ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Cron task

2021-11-27 22:33:58  阅读:192  来源: 互联网

标签:std task next Cron tm mon prev day


        int last_day_of_month(std::tm cur) const {
           if (cur.tm_mon + 1 > 11) {
              cur.tm_mon = 0;
              cur.tm_year++;
            } else {
              cur.tm_mon++;
            }
            cur.tm_mday = 1;
            cur.tm_hour = 0;
            cur.tm_min = 0;
            add(cur, std::chrono::hours(-24));
            return cur.tm_mday;
        }

        Clock::time_point cron_to_prev(const Clock::time_point from) const {
          int loop_times = 0;
          auto now = Clock::to_time_t(from);
          std::tm prev(*std::localtime(&now));
          std::tm old = prev;
          prev.tm_sec = 0;
          add(prev, std::chrono::minutes(-1)); // last min
          bool change_mon = false;
          bool change_day = false;
          bool change_week = false;
          bool change_hour = false;
          while (true) {
            if (loop_times++ > MAX_LOOP_TIMES) {
              printf("!!! seems dead loop in cron_to_prev !!!\n");
              return Clock::time_point(Clock::duration(0));
            }
            if (minute != -1 && prev.tm_min != minute) {
              add(prev, std::chrono::minutes(-1));
              continue;
            }
            if (hour != -1 && prev.tm_hour != hour) {
              add(prev, std::chrono::hours(-1));
              continue;
            }
            if (day != -1 && prev.tm_mday != day) {
              add(prev, std::chrono::hours(-24));
              continue;
            }
            if (day_of_week != -1 && prev.tm_wday != day_of_week) {
              add(prev, std::chrono::hours(-24));
              continue;
            }
            if (month != -1 && prev.tm_mon != month) {
              if (prev.tm_mon == 0) {
                prev.tm_mon = 11;
                prev.tm_year--;
              } else {
                prev.tm_mon--;
              }
              add(prev, std::chrono::seconds(0)); // bug fix
              continue;
            }
           
            break;
          }

          if (old.tm_hour != prev.tm_hour) {
            change_hour = true;
          }
          if (old.tm_mday != prev.tm_mday) {
            change_day = true;
          }
          if (old.tm_wday != prev.tm_wday) {
            change_week = true;
          }
          if (old.tm_mon != prev.tm_mon) {
            change_mon = true;
          }
          if (change_hour || change_day || change_week || change_mon) {
            if (minute == -1 
                 && (hour != -1 || day != -1 || day_of_week != -1 || month != -1)) {
              prev.tm_min = 59;
            }
          } 
          if (change_day || change_week || change_mon) {
            if (hour == -1 && (day != -1 || day_of_week != -1 || month != -1)) {
              prev.tm_hour = 23;
            }
          }
          if (change_mon) {
            if (day == -1 && month != -1) { // last day in this month
              prev.tm_mday = last_day_of_month(prev);// [1,31]
            }
          }
          if (change_week || change_mon) {
            if (month != -1 && day_of_week != -1) {  // last week-day in this month
              prev.tm_mday = last_day_of_month(prev); // last day in this month
              add(prev, std::chrono::seconds(0));
              while(true) {
                if (prev.tm_wday == day_of_week) {
                  break;
                }
                add(prev, std::chrono::hours(-24));
              }
            }
          }
          // telling mktime to figure out dst
          prev.tm_isdst = -1;
          return Clock::from_time_t(std::mktime(&prev));
        }

        // http://stackoverflow.com/a/322058/1284550
        Clock::time_point cron_to_next(const Clock::time_point) const {
          int loop_times = 0;
          auto now = Clock::to_time_t(from);
          std::tm next(*std::localtime(&now));
          // it will always at least run the next minute
          next.tm_sec = 0;
          add(next, std::chrono::minutes(1));
          while (true) {
            if (loop_times++ > MAX_LOOP_TIMES) {
              printf("!!! seems dead loop in cron_to_next !!!\n");
              return Clock::time_point(Clock::duration(0));
            }
            if (month != -1 && next.tm_mon != month) {

              if (next.tm_mon + 1 > 11) {
                next.tm_mon = 0;
                next.tm_year++;
              } else {
                next.tm_mon++;
              }
              next.tm_mday = 1;
              next.tm_hour = 0;
              next.tm_min = 0;
              add(next, std::chrono::seconds(0)); // bug fix
              continue;
            }

            if (day != -1 && next.tm_mday != day) {
              add(next, std::chrono::hours(24));
              next.tm_hour = 0;
              next.tm_min = 0;
              continue;
            }
            if (day_of_week != -1 && next.tm_wday != day_of_week) {
              add(next, std::chrono::hours(24));
              next.tm_hour = 0;
              next.tm_min = 0;
              continue;
            }
            if (hour != -1 && next.tm_hour != hour) {
              add(next, std::chrono::hours(1));
              next.tm_min = 0;
              continue;
            }
            if (minute != -1 && next.tm_min != minute) {
              add(next, std::chrono::minutes(1));
              continue;
            }
            break;
          }
          
          // telling mktime to figure out dst
          next.tm_isdst = -1;
          return Clock::from_time_t(std::mktime(&next));
        }


    Bosma::Cron cron("3 * 1 10 *");
    auto fromTp = try_parse("2010-03-06 10:10:00", "%Y-%m-%d %H:%M:%S");

标签:std,task,next,Cron,tm,mon,prev,day
来源: https://blog.csdn.net/venceinfo/article/details/120804043

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有