PHP獲取一段時間內的每個周幾,每月幾號,遇到特殊日子就往後延

myDCool發表於2016-11-01

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     ];

 


相關文章