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

来源:转载 发布时间:2018-10-15 15:11:58 阅读量:836

本篇文章给大家带来的内容是关于ThinkPHP中如何获取指定日期后工作日的具体日期 (代码详解),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

思路:

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

1

2

3

4

5

6

7

8

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

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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

<?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


标签: PHP
分享:
评论:
你还没有登录,请先