The specific date method in ThinkPHP to get the working day after the specified date

  • 2021-11-02 00:12:22
  • OfStack

Thoughts:

1. Obtain the data array of all working days in the query year
2. Get the index with the query start date on the working day
3. Calculate the date index to be queried
4. Get the query date


/* Create date type record table */

CREATE TABLE `tb_workday` (

`did` int(11) NOT NULL AUTO_INCREMENT,

`exact_date` varchar(32) NOT NULL COMMENT ' Specific date: format date("Ymd");(20170205)',

`date_year` varchar(32) NOT NULL COMMENT ' Specific date: format date("Y");(2017)',

`date_type` tinyint(2) NOT NULL COMMENT ' Date type: 0 , working days; 1 , special working days; 2 Legal holidays ',

PRIMARY KEY (`did`)

) ENGINE=InnoDB AUTO_INCREMENT=829 DEFAULT CHARSET=utf8 COMMENT=' Working days of each year & Legal holiday data '

<?php

 

class work_days

{

 /**

 *  Acquisition week 

 * @param $date

 * @return mixed

 */

 function get_week($date)

 {

 // Cast date format 

 $date_str = date('Y-m-d', strtotime($date));

 // Encapsulate into an array 

 $arr = explode("-", $date_str);

 // Parameter assignment 

 // Year 

 $year = $arr[0];

 // Month, output 2 Bit integer, not enough 2 Bit right alignment 

 $month = sprintf('%02d', $arr[1]);

 // Day, output 2 Bit integer, not enough 2 Bit right alignment 

 $day = sprintf('%02d', $arr[2]);

 // The default assignment of time division and second is 0 ; 

 $hour = $minute = $second = 0;

 // Convert to timestamp 

 $strap = mktime($hour, $minute, $second, $month, $day, $year);

 // Get the numeric day of the week 

 $number_wk = date("w", $strap);

 

 // Gets the week corresponding to the number 

 return $number_wk;

 

 // Custom week array 

 //$weekArr = array(" Sunday ", " Week 1", " Week 2", " Week 3", " Week 4", " Week 5", " Week 6");

 

 // Gets the week corresponding to the number 

 //return $weekArr[$number_wk];

 }

 

 

 /**

 *  Gets each of the specified date segments 1 Date of days 

 * @param string $startdate  Start date 

 * @param string $enddate  End date 

 * @return array

 */

 function getDateFromRange($startdate, $enddate)

 {

 $stimestamp = strtotime($startdate);

 $etimestamp = strtotime($enddate);

 

 //  Calculate how many days are in the date range 

 $days = ($etimestamp - $stimestamp) / 86400 + 1;

 

 //  Save Daily Date 

 $_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;

 }

 

 /**

 *  Update database specified year and date data 

 * @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';// Find it for free 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);

 

 // Workday 

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

 

 

 // Workday   Determine whether it is a weekend 

 if (in_array(self::get_week($_date), array(0, 1))) {

  // Special working days 

  $dateData['exact_date'] = $_date;

  $dateData['date_year'] = $year;

  $dateData['date_type'] = 1;

  $_ret = $m->add($dateData) ? 1 : 0;

  unset($dateData);

 }

 }

 

 // Legal holidays 

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

 }

 

 // Rest day ( Weekend )  Temporarily not processed 

 /*if ($_ret_curl['data'] == 1) {

 

 }*/

 $_ret && $count++;

 unset($_date, $_post_data, $_ret_curl, $_ret);

 }

 return $count;

 }

 

 /**

 *  Get all working days in the current year  ( Get from the database, update the data first if there is no data in the database )

 * @param string $year  Year of the 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 {

 // Update database workday data 

 $ret = self::updateDate($year);

 if ($ret > 0) {

 return self::getWorkDays($year);

 } else {

 return false;

 }

 }

 }

 

 /**

 *  Objects after the start date N Specific date of working days 

 * @param $startdate string  Calculate start date   You need to include year, month and day information 

 * @param $days int  Interval days 

 * @return mixed  Successful return   Corresponding date, failure returns 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) {// Query date is non-working 

 // Get the most recent working day before the query date 

 $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 {

 // The inquiry date has crossed the New Year 

 $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

The above code can be tested locally under 1, thank you for your support of this site.


Related articles: