需求:开发中有时会遇到工作日的问题,比如一个审批需要三个工作日,我们在录入的时候就需要知道三个工作日之后的日期。
原理:利用mysql存储未来指定天数的工作日时间戳,然后利用limit查找
1.调用方法:
$getTimeClass = new app\common\common\GetTime();
return $getTimeClass->get_after_date(5); //获取5个工作日之后的日期
2.类demo:
<?php
namespace app\common\common;
use think\facade\{Db,Config};
class GetTime {
/**
* [天行数据]
* [接口文档url:https://www.tianapi.com/apiview/139]
* @var [type]
*/
private $readme;
/**
* [天行数据接口地址]
* @var string
*/
private $base_url = "http://api.tianapi.com/txapi/jiejiari/index";
/**
* [天行数据接口秘钥]
* @var string
*/
private $key = "d5ebdaf781005a07a5ca77d62531bb0e";
/**
* [数据表前缀]
* @var [type]
*/
protected $tablePrefix;
/**
* [数据表名字]
* @var [type]
*/
protected $tableName;
/**
* [拉取天数]
* @var integer
*/
private $time = 120;
/**
* [构造函数初始化表前缀和表名称]
* @Author juming
* @DateTime 2021-01-26T16:18:07+0800
*/
public function __construct(){
$this->tablePrefix = Config::get('database.connections.mysql.prefix');
$this->tableName = "{$this->tablePrefix}workdays";
return $this;
}
/**
* [获取指定个工作日的日期]
* @Author juming
* @DateTime 2021-01-26T16:19:05+0800
* @param int $after [description]
* @return [type] [description]
*/
public function get_after_date(int $after){
if($after > 30){
throw new \Exception("Only query data within 30 days is supported");
}
self::check_table_exists();
$timestamp = self::get_before_dawn_time();
$data = Db::table($this->tableName)->where('timestamp','>',$timestamp)->limit($after)->column('timestamp');
if(count($data) != $after){
return self::request_and_get_data($after);
}
$end = end($data);
return date('Y-m-d',$end);
}
/**
* [请求天行接口拉取数据]
* @Author juming
* @DateTime 2021-01-26T16:20:39+0800
* @param int $after [description]
* @return [type] [description]
*/
protected function request_and_get_data(int $after){
set_time_limit(0);
$timestamp = self::get_last_date();
for($i=1;$i<=$this->time;$i++){
$date = date('Y-m-d',$timestamp + $i*86400);
$get_url = self::get_url($date);
$res = json_decode(file_get_contents($get_url),true);
if($res['code'] != 200){
throw new \Exception("接口调用失败(错误码:".$res['code'].")");
}
if($res['newslist'][0]['isnotwork'] == 0){
$insert['timestamp'] = strtotime($date);
Db::table($this->tableName)->insert($insert);
}
}
return self::get_after_date($after);
}
/**
* [获取接口的url]
* @Author juming
* @DateTime 2021-01-26T16:21:41+0800
* @param String $date [description]
* @return [type] [description]
*/
private function get_url(String $date){
return $this->base_url.'?key='.$this->key.'&date='.$date;
}
/**
* [获取数据表中最后的数据日期]
* @Author juming
* @DateTime 2021-01-26T16:22:47+0800
* @return [type] [description]
*/
private function get_last_date(){
$timestamp = Db::table($this->tableName)->order('id','desc')->limit(1)->value('timestamp');
$timestamp = $timestamp ? $timestamp :$this->get_before_dawn_time();;
return $timestamp;
}
/**
* [获取当日凌晨时间戳]
* @Author juming
* @DateTime 2021-01-26T16:23:12+0800
* @return [type] [description]
*/
protected function get_before_dawn_time(){
return strtotime(date('Y-m-d'));
}
/**
* [检查表是否存在]
* @Author juming
* @DateTime 2021-01-26T16:23:34+0800
* @return [type] [description]
*/
protected function check_table_exists(){
$check = Db::query("show tables like '{$this->tableName}'");
if (empty($check)) {
$sql = self::getCreateSql();
Db::execute($sql);
}
}
/**
* [创建数据表sql语句]
* @Author juming
* @DateTime 2021-01-26T16:23:58+0800
* @return [type] [description]
*/
protected function getCreateSql(){
return <<<EOT
CREATE TABLE `{$this->tableName}` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`timestamp` int(11) DEFAULT '0' COMMENT '当日时间戳',
PRIMARY KEY (`id`),
KEY `timestamp` (`timestamp`) USING BTREE COMMENT '当日凌晨时间戳索引'
) ENGINE=MyISAM AUTO_INCREMENT=61 DEFAULT CHARSET=utf8 COMMENT='工作日记录表';
EOT;
}
}
3.说明:
调用类方法时,会首先检查数据库中workdays表是否存在,如果不存在会自动创建workdays表,无需手动创建,使用前请确保数据库配置正确。
网友评论