首页 / php教程

    ThinkPHP中如何获取指定日期后工作日的具体日期 (代码详解)

    作者:PHP中文网2018-10-13 15:00:15

    php中文网赞助会员本篇文章给大家带来的内容是关于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='各年工作日&法定节假日数据'
    <?php
    
    class work_days
    {
      /**
       * 获取星期
       * @param $date
       * @return mixed
       */
      function get_week($date)
      {
        //强制转换日期格式
        $date_str = date('Y-m-d', strtotime($date));
        //封装成数组
        $arr = explode("-", $date_str);
        //参数赋值
        //年
        $year = $arr[0];
        //月,输出2位整型,不够2位右对齐
        $month = sprintf('%02d', $arr[1]);
        //日,输出2位整型,不够2位右对齐
        $day = sprintf('%02d', $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('Y-m-d', $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('Y-m-d', strtotime($year . '-01-01'));
        $endDate = date('Y-m-d', strtotime('+1 year', strtotime($startDate)) - 86400);
        $_list_date = self::getDateFromRange($startDate, $endDate);
    
        $url = 'http://api.goseek.cn/Tools/holiday';//自行查找的免费API
    
        $m = M('tb_workday');
        $count = 0;
    
        foreach ($_list_date as $k => $_date) {
          $_ret = 0;
          $_date = date('Ymd', strtotime($_date));
          $_post_data = array('date' => $_date);
          $_ret_curl = curl_post($url, $_post_data);
          $_ret_curl = json_decode($_ret_curl, true);
    
          //工作日
          if ($_ret_curl['data'] == 0) {
            $dateData['exact_date'] = $_date;
            $dateData['date_year'] = $year;
            $dateData['date_type'] = 0;
            $_ret = $m->add($dateData) ? 1 : 0;
            unset($dateData);
    
    
            //工作日 判断是否为周末
            if (in_array(self::get_week($_date), array(0, 1))) {
              //特殊工作日
              $dateData['exact_date'] = $_date;
              $dateData['date_year'] = $year;
              $dateData['date_type'] = 1;
              $_ret = $m->add($dateData) ? 1 : 0;
              unset($dateData);
            }
          }
    
          //法定节假日
          if ($_ret_curl['data'] == 2) {
            $dateData['exact_date'] = $_date;
            $dateData['date_year'] = $year;
            $dateData['date_type'] = 2;
            $_ret = $m->add($dateData) ? 1 : 0;
            unset($dateData);
          }
    
          //休息日(周末) 暂不处理
          /*if ($_ret_curl['data'] == 1) {
    
          }*/
          $_ret && $count++;
          unset($_date, $_post_data, $_ret_curl, $_ret);
        }
        return $count;
      }
    
      /**
       * 获取当年所有工作日 (从数据库获取,数据库无数据则先更新数据)
       * @param string $year 当年年份
       * @return array
       */
      private function getWorkDays($year)
      {
        $m = M('tb_workday');
        $map['date_year'] = $year;
        $map['date_type'] = 0;
        $DateArray = $m->field('exact_date')->where($map)->select();
        if (!empty($DateArray)) {
          $DateArray = array_column($DateArray, 'exact_date');
          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('Y', strtotime($startdate));
        $startdate = date('Y-m-d', strtotime($startdate));
    
        $workDays = $this->getWorkDays($year);
    
        $search_key = array_search(date('Ymd', strtotime($startdate)), $workDays);
    
        if ($search_key === false) {//查询日期为非工作
          //获取查询日期前最近工作日
          $m = M('tb_workday');
          $map['date_year'] = $year;
          $map['date_type'] = 0;
          $map['DATE_FORMAT(`exact_date`,\'%Y-%m-%d\')'] = array('LT', $startdate);
          $_search_date = $m->where($map)->order('`exact_date` DESC')->getField('exact_date');
          $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('Y-m-d', strtotime($workDays[$t_key]));
        } else {
          //查询日期已跨年
          $n_days = $days - (count($workDays) - 1 - $search_key);
          $next_year = $year + 1;
          return $this->getNextWorkDate($next_year . '-01-01', $n_days - 1);
        }
      }
    }
    
    
    $startdate = '2018-09-28';
    $days = 5;
    
    $class = new work_days();
    $_date_workday = $class->getNextWorkDate($startdate, $days);
    echo $_date_workday;//2018-10-10

    以上就是ThinkPHP中如何获取指定日期后工作日的具体日期 (代码详解)的详细内容,更多请关注php中文网其它相关文章!

    标签:

PHP中文网

未登录