zoukankan      html  css  js  c++  java
  • PHP获取一段时间内的每个周几, 每月几号, 遇到特殊日子就往后延

    2016年11月1日 16:18:19 星期二

    主要用到的函数是 strtotime()

    strtotime('+1 Tuesday', $timestamp) 获取下周二, 从时间戳$timestamp开始计算, 如果$timestamp留空, 则从当天开始计算

    strtotime('+1 month', $timestamp) 获取下个月的x号, 还是以$timestamp开始计算的

      1 /**
      2      * desc 获取每周X执行的所有日期
      3      * @param string $start 开始日期, 2016-10-17
      4      * @param string $end 结束日期, 2016-10-17
      5      * @param int $weekDay 1~5
      6      * @return array
      7      */
      8     public function getWeeklyBuyDate($start, $end, $weekDay)
      9     {
     10         //获取每周要执行的日期 例如: 2016-01-02
     11         $start = empty($start) ? date('Y-m-d') : $start;
     12         $startTime = strtotime($start);
     13 
     14         $startDay = date('N', $startTime);
     15         if ($startDay < $weekDay) {
     16             $startTime = strtotime(self::$WORK_DAY[$weekDay]['en'], strtotime($start)); //本周x开始, 例如, 今天(周二)用户设置每周四执行, 那本周四就会开始执行
     17         } else {
     18             $startTime = strtotime('next '.self::$WORK_DAY[$weekDay]['en'], strtotime($start));//下一个周x开始, 今天(周二)用户设置每周一执行, 那应该是下周一开始执行
     19         }
     20 
     21         $endTime = strtotime($end);
     22         $list = [];
     23         for ($i=0;;$i++) {
     24             $dayOfWeek = strtotime("+{$i} week", $startTime); //每周x
     25             if ($dayOfWeek > $endTime) {
     26                 break;
     27             }
     28             $list[] = date('Y-m-d', $dayOfWeek);
     29         }
     30 
     31         return $this->getExedate($start, $end, $list);
     32     }
     33 
     34     /**
     35      * desc 获取每月X号执行的所有日期
     36      * @param string $start 开始日期, 2016-10-17
     37      * @param string $end 结束日期, 2016-10-17
     38      * @param int $monthDay 1~28
     39      * @return array
     40      */
     41     public function getMonthlyBuyDate($start, $end, $monthDay)
     42     {
     43         $monthDay = str_pad($monthDay, 2, '0', STR_PAD_LEFT); //左边补零
     44         $start = empty($start) ? date('Y-m-d') : $start;
     45         $startTime = strtotime($start);
     46         $startDay = substr($start, 8, 2);
     47 
     48         if (strcmp($startDay, $monthDay) < 0) {
     49             $startMonthDayTime = strtotime(date('Y-m-', strtotime($start)).$monthDay); //本月开始执行, 今天(例如,26号)用户设置每月28号执行, 那么本月就开始执行
     50         } else  {
     51             $startMonthDayTime = strtotime(date('Y-m-', strtotime('+1 month', $startTime)).$monthDay); //从下个月开始
     52         }
     53         $endTime = strtotime($end);
     54 
     55         $list = [];
     56         for ($i=0;;$i++) {
     57             $dayOfMonth = strtotime("+{$i} month", $startMonthDayTime);//每月x号
     58             if ($dayOfMonth > $endTime) {
     59                 break;
     60             }
     61             $list[] = date('Y-m-d', $dayOfMonth);
     62         }
     63         
     64         return $this->getExedate($start, $end, $list);
     65 
     66     }
     67 
     68     /**
     69      * desc 返回顺延后的执行日期列表
     70      * @param string $start 开始日期, 2016-10-17
     71      * @param string $end 结束日期, 2016-10-17
     72      * @param array $planDate
     73      * @return array
     74      */
     75     public function getExedate($start, $end, $planDate)
     76     {
     77         //获取所有交易日
     78         $allTradeDate = $this->getTradeDate($start, $end);
     79 
     80         //取最后一个交易日
     81         $endTradeDate = end($allTradeDate); //返回格式: ['2016-11-01' => '2016-11-01', '2016-11-02' => '2016-11-02', ...], 有冗余,方便编程
     82 
     83         $exeDate = []; //顺延后的执行日期
     84         foreach ($planDate as $date) {
     85             if (!empty($allTradeDate[$date])) {
     86                 $exeDate[$date] = $date;
     87             } else { //没找到, 需要往后顺延到下一个交易日
     88                 $exeDate[$date] = '';
     89 
     90                 $endTradeTime = strtotime($endTradeDate);
     91                 $currentTime = strtotime($date);
     92 
     93                 for ($i=$currentTime; $i<=$endTradeTime; $i+=86400) {//一天一天往后顺延, 直到找到下一个交易日, 直到数据库存储的最后一个交易日
     94                     $tmpDate = date('Y-m-d', $i);
     95                     if (!empty($allTradeDate[$tmpDate])) { //找到就退出循环
     96                         $exeDate[$date] = $tmpDate;
     97                         break;
     98                     }
     99                 }
    100             }
    101         }
    102 
    103         return $exeDate;
    104     }
    

     其中:

    1 public static $WORK_DAY = [
    2         1 => ['en' => 'Monday', 'cn' => '一'],
    3         2 => ['en' => 'Tuesday', 'cn' => '二'],
    4         3 => ['en' => 'Wednesday', 'cn' => '三'],
    5         4 => ['en' => 'Thursday', 'cn' => '四'],
    6         5 => ['en' => 'Friday', 'cn' => '五']
    7     ];
    
  • 相关阅读:
    Net学习日记_SQL_1
    Net学习日记_基础提高_11_俄罗斯方块_代码篇
    Net学习日记_基础提高_11_俄罗斯方块_整理概括篇
    Net学习日记_基础提高_10
    C#抽象类和接口
    RSS大全
    如何使用deparam.js抓参数
    h5页面解决软键盘与100%X100%的页面的冲突
    29、数据库三大范式精要总结
    28、数据库三大范式精讲
  • 原文地址:https://www.cnblogs.com/bluealine/p/7271399.html
Copyright © 2011-2022 走看看