Maison  >  Article  >  développement back-end  >  Comment obtenir la date spécifique du jour ouvrable après la date spécifiée dans ThinkPHP (explication détaillée du code)

Comment obtenir la date spécifique du jour ouvrable après la date spécifiée dans ThinkPHP (explication détaillée du code)

不言
不言avant
2018-10-13 15:00:152640parcourir

Le contenu de cet article explique comment obtenir la date spécifique du jour ouvrable après la date spécifiée dans ThinkPHP (explication détaillée du code). J'espère que les amis dans le besoin pourront s'y référer. être utile pour vous aider.

Idée :

1. Obtenez le tableau de données de tous les jours ouvrables de l'année de requête
2. Obtenez l'index de la date de début de la requête sur les jours ouvrables
3. Calculez la date à interroger Index
4 Obtenez la date de requête

/*创建日期类型记录表格*/
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='各年工作日&法定节假日数据'
<?php

class work_days
{
  /**
   * 获取星期
   * @param $date
   * @return mixed
   */
  function get_week($date)
  {
    //强制转换日期格式
    $date_str = date(&#39;Y-m-d&#39;, strtotime($date));
    //封装成数组
    $arr = explode("-", $date_str);
    //参数赋值
    //年
    $year = $arr[0];
    //月,输出2位整型,不够2位右对齐
    $month = sprintf(&#39;%02d&#39;, $arr[1]);
    //日,输出2位整型,不够2位右对齐
    $day = sprintf(&#39;%02d&#39;, $arr[2]);
    //时分秒默认赋值为0;
    $hour = $minute = $second = 0;
    //转换成时间戳
    $strap = mktime($hour, $minute, $second, $month, $day, $year);
    //获取数字型星期几
    $number_wk = date("w", $strap);

    //获取数字对应的星期
    return $number_wk;

    //自定义星期数组
    //$weekArr = array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");

    //获取数字对应的星期
    //return $weekArr[$number_wk];
  }


  /**
   * 获取指定日期段内每一天的日期
   * @param  string $startdate 开始日期
   * @param  string $enddate   结束日期
   * @return array
   */
  function getDateFromRange($startdate, $enddate)
  {
    $stimestamp = strtotime($startdate);
    $etimestamp = strtotime($enddate);

    // 计算日期段内有多少天
    $days = ($etimestamp - $stimestamp) / 86400 + 1;

    // 保存每天日期
    $_list_date = array();
    for ($i = 0; $i < $days; $i++) {
      $_list_date[] = date(&#39;Y-m-d&#39;, $stimestamp + (86400 * $i));
    }
    return $_list_date;
  }

  function curl_post($url, $data = null)
  {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    if (!empty($data)) {
      curl_setopt($curl, CURLOPT_POST, 1);
      curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    curl_close($curl);
    return $output;
  }

  /**
   * 更新数据库指定年份日期数据
   * @param $year
   * @return int
   */
  function updateDate($year)
  {
    $startDate = date(&#39;Y-m-d&#39;, strtotime($year . &#39;-01-01&#39;));
    $endDate = date(&#39;Y-m-d&#39;, strtotime(&#39;+1 year&#39;, strtotime($startDate)) - 86400);
    $_list_date = self::getDateFromRange($startDate, $endDate);

    $url = &#39;http://api.goseek.cn/Tools/holiday&#39;;//自行查找的免费API

    $m = M(&#39;tb_workday&#39;);
    $count = 0;

    foreach ($_list_date as $k => $_date) {
      $_ret = 0;
      $_date = date(&#39;Ymd&#39;, strtotime($_date));
      $_post_data = array(&#39;date&#39; => $_date);
      $_ret_curl = curl_post($url, $_post_data);
      $_ret_curl = json_decode($_ret_curl, true);

      //工作日
      if ($_ret_curl[&#39;data&#39;] == 0) {
        $dateData[&#39;exact_date&#39;] = $_date;
        $dateData[&#39;date_year&#39;] = $year;
        $dateData[&#39;date_type&#39;] = 0;
        $_ret = $m->add($dateData) ? 1 : 0;
        unset($dateData);


        //工作日 判断是否为周末
        if (in_array(self::get_week($_date), array(0, 1))) {
          //特殊工作日
          $dateData[&#39;exact_date&#39;] = $_date;
          $dateData[&#39;date_year&#39;] = $year;
          $dateData[&#39;date_type&#39;] = 1;
          $_ret = $m->add($dateData) ? 1 : 0;
          unset($dateData);
        }
      }

      //法定节假日
      if ($_ret_curl[&#39;data&#39;] == 2) {
        $dateData[&#39;exact_date&#39;] = $_date;
        $dateData[&#39;date_year&#39;] = $year;
        $dateData[&#39;date_type&#39;] = 2;
        $_ret = $m->add($dateData) ? 1 : 0;
        unset($dateData);
      }

      //休息日(周末) 暂不处理
      /*if ($_ret_curl[&#39;data&#39;] == 1) {

      }*/
      $_ret && $count++;
      unset($_date, $_post_data, $_ret_curl, $_ret);
    }
    return $count;
  }

  /**
   * 获取当年所有工作日 (从数据库获取,数据库无数据则先更新数据)
   * @param string $year 当年年份
   * @return array
   */
  private function getWorkDays($year)
  {
    $m = M(&#39;tb_workday&#39;);
    $map[&#39;date_year&#39;] = $year;
    $map[&#39;date_type&#39;] = 0;
    $DateArray = $m->field(&#39;exact_date&#39;)->where($map)->select();
    if (!empty($DateArray)) {
      $DateArray = array_column($DateArray, &#39;exact_date&#39;);
      return $DateArray;
    } else {
      //更新数据库工作日数据
      $ret = self::updateDate($year);
      if ($ret > 0) {
        return self::getWorkDays($year);
      } else {
        return false;
      }
    }
  }

  /**
   * 获取开始日期后第N个工作日具体日期
   * @param $startdate string 计算开始日期  需包含年月日信息
   * @param $days      int 间隔天数
   * @return mixed 成功返回 对应日期,失败返回false
   */
  public function getNextWorkDate($startdate, $days)
  {
    $year = date(&#39;Y&#39;, strtotime($startdate));
    $startdate = date(&#39;Y-m-d&#39;, strtotime($startdate));

    $workDays = $this->getWorkDays($year);

    $search_key = array_search(date(&#39;Ymd&#39;, strtotime($startdate)), $workDays);

    if ($search_key === false) {//查询日期为非工作
      //获取查询日期前最近工作日
      $m = M(&#39;tb_workday&#39;);
      $map[&#39;date_year&#39;] = $year;
      $map[&#39;date_type&#39;] = 0;
      $map[&#39;DATE_FORMAT(`exact_date`,\&#39;%Y-%m-%d\&#39;)&#39;] = array(&#39;LT&#39;, $startdate);
      $_search_date = $m->where($map)->order(&#39;`exact_date` DESC&#39;)->getField(&#39;exact_date&#39;);
      $search_key = array_search($_search_date, $workDays);
      unset($m, $map, $_search_date);
    }

    $t_key = $search_key + $days;

    if ($t_key <= count($workDays) - 1) {
      return date(&#39;Y-m-d&#39;, strtotime($workDays[$t_key]));
    } else {
      //查询日期已跨年
      $n_days = $days - (count($workDays) - 1 - $search_key);
      $next_year = $year + 1;
      return $this->getNextWorkDate($next_year . &#39;-01-01&#39;, $n_days - 1);
    }
  }
}


$startdate = &#39;2018-09-28&#39;;
$days = 5;

$class = new work_days();
$_date_workday = $class->getNextWorkDate($startdate, $days);
echo $_date_workday;//2018-10-10
.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer