ThinkPHP中如何获取指定日期后工作日的具体日期

Posted 心之所依

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThinkPHP中如何获取指定日期后工作日的具体日期相关的知识,希望对你有一定的参考价值。

思路:

1、获取到查询年份内所有工作日数据数组
2、获取到查询开始日期在工作日的索引
3、计算需查询日期索引
4、获得查询日期

/*创建日期类型记录表格*/

CREATE TABLE `tb_workday` (

`did` int(11) NOT NULL AUTO_INCREMENT,

`exact_date` varchar(32) NOT NULL COMMENT ‘具体日期:格式date("Ymd");(20170205)‘,

`date_year` varchar(32) NOT NULL COMMENT ‘具体日期:格式date("Y");(2017)‘,

`date_type` tinyint(2) NOT NULL COMMENT ‘日期类型:0、工作日;1、特殊工作日;2、法定节假日‘,

PRIMARY KEY (`did`)

) ENGINE=InnoDB AUTO_INCREMENT=829 DEFAULT CHARSET=utf8 COMMENT=‘各年工作日&法定节假日数据‘
  1 <?php
  2 
  3 class work_days
  4 {
  5   /**
  6    * 获取星期
  7    * @param $date
  8    * @return mixed
  9    */
 10   function get_week($date)
 11   {
 12     //强制转换日期格式
 13     $date_str = date(‘Y-m-d‘, strtotime($date));
 14     //封装成数组
 15     $arr = explode("-", $date_str);
 16     //参数赋值
 17     //年
 18     $year = $arr[0];
 19     //月,输出2位整型,不够2位右对齐
 20     $month = sprintf(‘%02d‘, $arr[1]);
 21     //日,输出2位整型,不够2位右对齐
 22     $day = sprintf(‘%02d‘, $arr[2]);
 23     //时分秒默认赋值为0;
 24     $hour = $minute = $second = 0;
 25     //转换成时间戳
 26     $strap = mktime($hour, $minute, $second, $month, $day, $year);
 27     //获取数字型星期几
 28     $number_wk = date("w", $strap);
 29     //获取数字对应的星期
 30     return $number_wk;
 31     //自定义星期数组
 32     //$weekArr = array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");
 33     //获取数字对应的星期
 34     //return $weekArr[$number_wk];
 35   }
 36 
 37   /**
 38    * 获取指定日期段内每一天的日期
 39    * @param  string $startdate 开始日期
 40    * @param  string $enddate   结束日期
 41    * @return array
 42    */
 43   function getDateFromRange($startdate, $enddate)
 44   {
 45     $stimestamp = strtotime($startdate);
 46     $etimestamp = strtotime($enddate);
 47     // 计算日期段内有多少天
 48     $days = ($etimestamp - $stimestamp) / 86400 + 1;
 49     // 保存每天日期
 50     $_list_date = array();
 51     for ($i = 0; $i < $days; $i++) {
 52       $_list_date[] = date(‘Y-m-d‘, $stimestamp + (86400 * $i));
 53     }
 54     return $_list_date;
 55   }
 56 
 57   function curl_post($url, $data = null)
 58   {
 59     $curl = curl_init();
 60     curl_setopt($curl, CURLOPT_URL, $url);
 61     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
 62     curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
 63     if (!empty($data)) {
 64       curl_setopt($curl, CURLOPT_POST, 1);
 65       curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
 66     }
 67     curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
 68     $output = curl_exec($curl);
 69     curl_close($curl);
 70     return $output;
 71   }
 72 
 73 
 74   /**
 75    * 更新数据库指定年份日期数据
 76    * @param $year
 77    * @return int
 78    */
 79   function updateDate($year)
 80   {
 81     $startDate = date(‘Y-m-d‘, strtotime($year . ‘-01-01‘));
 82     $endDate = date(‘Y-m-d‘, strtotime(‘+1 year‘, strtotime($startDate)) - 86400);
 83     $_list_date = self::getDateFromRange($startDate, $endDate);
 84     $url = ‘http://api.goseek.cn/Tools/holiday‘;//自行查找的免费API
 85     $m = M(‘tb_workday‘);
 86     $count = 0;
 87     foreach ($_list_date as $k => $_date) {
 88       $_ret = 0;
 89       $_date = date(‘Ymd‘, strtotime($_date));
 90       $_post_data = array(‘date‘ => $_date);
 91       $_ret_curl = curl_post($url, $_post_data);
 92       $_ret_curl = json_decode($_ret_curl, true);
 93 
 94       //工作日
 95       if ($_ret_curl[‘data‘] == 0) {
 96         $dateData[‘exact_date‘] = $_date;
 97         $dateData[‘date_year‘] = $year;
 98         $dateData[‘date_type‘] = 0;
 99         $_ret = $m->add($dateData) ? 1 : 0;
100         unset($dateData);
101 
102 
103         //工作日 判断是否为周末
104         if (in_array(self::get_week($_date), array(0, 1))) {
105           //特殊工作日
106           $dateData[‘exact_date‘] = $_date;
107           $dateData[‘date_year‘] = $year;
108           $dateData[‘date_type‘] = 1;
109           $_ret = $m->add($dateData) ? 1 : 0;
110           unset($dateData);
111         }
112       }
113 
114       //法定节假日
115       if ($_ret_curl[‘data‘] == 2) {
116         $dateData[‘exact_date‘] = $_date;
117         $dateData[‘date_year‘] = $year;
118         $dateData[‘date_type‘] = 2;
119         $_ret = $m->add($dateData) ? 1 : 0;
120         unset($dateData);
121       }
122 
123       //休息日(周末) 暂不处理
124       /*if ($_ret_curl[‘data‘] == 1) {
125 
126       }*/
127 
128       $_ret && $count++;
129       unset($_date, $_post_data, $_ret_curl, $_ret);
130     }
131     return $count;
132   }
133 
134 
135   /**
136    * 获取当年所有工作日 (从数据库获取,数据库无数据则先更新数据)
137    * @param string $year 当年年份
138    * @return array
139    */
140   private function getWorkDays($year)
141   {
142     $m = M(‘tb_workday‘);
143     $map[‘date_year‘] = $year;
144     $map[‘date_type‘] = 0;
145     $DateArray = $m->field(‘exact_date‘)->where($map)->select();
146     if (!empty($DateArray)) {
147       $DateArray = array_column($DateArray, ‘exact_date‘);
148       return $DateArray;
149     } else {
150       //更新数据库工作日数据
151       $ret = self::updateDate($year);
152       if ($ret > 0) {
153         return self::getWorkDays($year);
154       } else {
155         return false;
156       }
157     }
158   }
159 
160   /**
161    * 获取开始日期后第N个工作日具体日期
162    * @param $startdate string 计算开始日期  需包含年月日信息
163    * @param $days      int 间隔天数
164    * @return mixed 成功返回 对应日期,失败返回false
165    */
166   public function getNextWorkDate($startdate, $days)
167   {
168     $year = date(‘Y‘, strtotime($startdate));
169     $startdate = date(‘Y-m-d‘, strtotime($startdate));
170     $workDays = $this->getWorkDays($year);
171     $search_key = array_search(date(‘Ymd‘, strtotime($startdate)), $workDays);
172     if ($search_key === false) {//查询日期为非工作
173       //获取查询日期前最近工作日
174       $m = M(‘tb_workday‘);
175       $map[‘date_year‘] = $year;
176       $map[‘date_type‘] = 0;
177       $map[‘DATE_FORMAT(`exact_date`,‘%Y-%m-%d‘)‘] = array(‘LT‘, $startdate);
178       $_search_date = $m->where($map)->order(‘`exact_date` DESC‘)->getField(‘exact_date‘);
179       $search_key = array_search($_search_date, $workDays);
180       unset($m, $map, $_search_date);
181     }
182     $t_key = $search_key + $days;
183     if ($t_key <= count($workDays) - 1) {
184       return date(‘Y-m-d‘, strtotime($workDays[$t_key]));
185     } else {
186       //查询日期已跨年
187       $n_days = $days - (count($workDays) - 1 - $search_key);
188       $next_year = $year + 1;
189       return $this->getNextWorkDate($next_year . ‘-01-01‘, $n_days - 1);
190     }
191   }
192 }
193 
194 $startdate = ‘2018-09-28‘;
195 $days = 5;
196 
197 $class = new work_days();
198 $_date_workday = $class->getNextWorkDate($startdate, $days);
199 echo $_date_workday;//2018-10-10



以上是关于ThinkPHP中如何获取指定日期后工作日的具体日期的主要内容,如果未能解决你的问题,请参考以下文章

c#中,如何获取日期型字段里的年、月、日?

有关java中工作日算法的问题

ThinkPHP 如何把获取到的日期格式的时间转化为时间戳

java - 如何从Java日历中获取指定周的星期六日期? [关闭]

EXCEL如何获取当前日期时间

如何利用PHP时间戳获取当前时间