ThinkPHP中获取指定日期后工作日的具体日期方法

在本文中,我们给大家带来的是关于ThinkPHP中获取指定日期后工作日的具体日期的方法以及实例代码,有需要的朋友们学习下。

思路:

1、获取到查询年份内所有工作日数据数组

2、获取到查询开始日期在工作日的索引

3、计算需查询日期索引

4、获得查询日期

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