Completed
Push — 6.0 ( be0b6e...c47dd5 )
by liu
06:54 queued 10s
created

TimeFieldQuery   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 191
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 38
dl 0
loc 191
ccs 0
cts 39
cp 0
rs 10
c 0
b 0
f 0
wmc 20

11 Methods

Rating   Name   Duplication   Size   Complexity  
A whereNotBetweenTimeField() 0 4 1
A whereBetweenTimeField() 0 4 1
A whereMonth() 0 7 2
A whereWeek() 0 7 2
A whereNotBetweenTime() 0 4 1
A whereBetweenTime() 0 3 1
A whereDay() 0 7 2
A whereYear() 0 7 2
A whereTime() 0 8 3
A whereTimeInterval() 0 6 4
A timeRule() 0 4 1
1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think\db\concern;
14
15
/**
16
 * 时间查询支持
17
 */
18
trait TimeFieldQuery
19
{
20
    /**
21
     * 日期查询表达式
22
     * @var array
23
     */
24
    protected $timeRule = [
25
        'today'      => ['today', 'tomorrow'],
26
        'yesterday'  => ['yesterday', 'today'],
27
        'week'       => ['this week 00:00:00', 'next week 00:00:00'],
28
        'last week'  => ['last week 00:00:00', 'this week 00:00:00'],
29
        'month'      => ['first Day of this month 00:00:00', 'first Day of next month 00:00:00'],
30
        'last month' => ['first Day of last month 00:00:00', 'first Day of this month 00:00:00'],
31
        'year'       => ['this year 1/1', 'next year 1/1'],
32
        'last year'  => ['last year 1/1', 'this year 1/1'],
33
    ];
34
35
    /**
36
     * 添加日期或者时间查询规则
37
     * @access public
38
     * @param string       $name 时间表达式
39
     * @param string|array $rule 时间范围
40
     * @return $this
41
     */
42
    public function timeRule(string $name, $rule)
43
    {
44
        $this->timeRule[$name] = $rule;
45
        return $this;
46
    }
47
48
    /**
49
     * 查询日期或者时间
50
     * @access public
51
     * @param string       $field 日期字段名
52
     * @param string       $op    比较运算符或者表达式
53
     * @param string|array $range 比较范围
54
     * @param string       $logic AND OR
55
     * @return $this
56
     */
57
    public function whereTime(string $field, string $op, $range = null, string $logic = 'AND')
58
    {
59
        if (is_null($range) && isset($this->timeRule[$op])) {
60
            $range = $this->timeRule[$op];
61
            $op    = 'between';
62
        }
63
64
        return $this->parseWhereExp($logic, $field, strtolower($op) . ' time', $range, [], true);
0 ignored issues
show
Bug introduced by
It seems like parseWhereExp() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

64
        return $this->/** @scrutinizer ignore-call */ parseWhereExp($logic, $field, strtolower($op) . ' time', $range, [], true);
Loading history...
65
    }
66
67
    /**
68
     * 查询某个时间间隔数据
69
     * @access public
70
     * @param string $field    日期字段名
71
     * @param string $start    开始时间
72
     * @param string $interval 时间间隔单位 day/month/year/week/hour/minute/second
73
     * @param int    $step     间隔
74
     * @param string $logic    AND OR
75
     * @return $this
76
     */
77
    public function whereTimeInterval(string $field, string $start, string $interval = 'day', int $step = 1, string $logic = 'AND')
78
    {
79
        $startTime = strtotime($start);
80
        $endTime   = strtotime(($step > 0 ? '+' : '-') . abs($step) . ' ' . $interval . (abs($step) > 1 ? 's' : ''), $startTime);
81
82
        return $this->whereTime($field, 'between', $step > 0 ? [$startTime, $endTime] : [$endTime, $startTime], $logic);
83
    }
84
85
    /**
86
     * 查询月数据 whereMonth('time_field', '2018-1')
87
     * @access public
88
     * @param string $field 日期字段名
89
     * @param string $month 月份信息
90
     * @param int    $step  间隔
91
     * @param string $logic AND OR
92
     * @return $this
93
     */
94
    public function whereMonth(string $field, string $month = 'this month', int $step = 1, string $logic = 'AND')
95
    {
96
        if (in_array($month, ['this month', 'last month'])) {
97
            $month = date('Y-m', strtotime($month));
98
        }
99
100
        return $this->whereTimeInterval($field, $month, 'month', $step, $logic);
101
    }
102
103
    /**
104
     * 查询周数据 whereWeek('time_field', '2018-1-1') 从2018-1-1开始的一周数据
105
     * @access public
106
     * @param string $field 日期字段名
107
     * @param string $week  周信息
108
     * @param int    $step  间隔
109
     * @param string $logic AND OR
110
     * @return $this
111
     */
112
    public function whereWeek(string $field, string $week = 'this week', int $step = 1, string $logic = 'AND')
113
    {
114
        if (in_array($week, ['this week', 'last week'])) {
115
            $week = date('Y-m-d', strtotime($week));
116
        }
117
118
        return $this->whereTimeInterval($field, $week, 'week', $step, $logic);
119
    }
120
121
    /**
122
     * 查询年数据 whereYear('time_field', '2018')
123
     * @access public
124
     * @param string $field 日期字段名
125
     * @param string $year  年份信息
126
     * @param int    $step     间隔
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 5 found
Loading history...
127
     * @param string $logic AND OR
128
     * @return $this
129
     */
130
    public function whereYear(string $field, string $year = 'this year', int $step = 1, string $logic = 'AND')
131
    {
132
        if (in_array($year, ['this year', 'last year'])) {
133
            $year = date('Y', strtotime($year));
134
        }
135
136
        return $this->whereTimeInterval($field, $year . '-1-1', 'year', $step, $logic);
137
    }
138
139
    /**
140
     * 查询日数据 whereDay('time_field', '2018-1-1')
141
     * @access public
142
     * @param string $field 日期字段名
143
     * @param string $day   日期信息
144
     * @param int    $step     间隔
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter name; 5 found
Loading history...
145
     * @param string $logic AND OR
146
     * @return $this
147
     */
148
    public function whereDay(string $field, string $day = 'today', int $step = 1, string $logic = 'AND')
149
    {
150
        if (in_array($day, ['today', 'yesterday'])) {
151
            $day = date('Y-m-d', strtotime($day));
152
        }
153
154
        return $this->whereTimeInterval($field, $day, 'day', $step, $logic);
155
    }
156
157
    /**
158
     * 查询日期或者时间范围 whereBetweenTime('time_field', '2018-1-1','2018-1-15')
159
     * @access public
160
     * @param string     $field     日期字段名
161
     * @param string|int $startTime 开始时间
162
     * @param string|int $endTime   结束时间
163
     * @param string     $logic     AND OR
164
     * @return $this
165
     */
166
    public function whereBetweenTime(string $field, $startTime, $endTime, string $logic = 'AND')
167
    {
168
        return $this->whereTime($field, 'between', [$startTime, $endTime], $logic);
169
    }
170
171
    /**
172
     * 查询日期或者时间范围 whereNotBetweenTime('time_field', '2018-1-1','2018-1-15')
173
     * @access public
174
     * @param string     $field     日期字段名
175
     * @param string|int $startTime 开始时间
176
     * @param string|int $endTime   结束时间
177
     * @return $this
178
     */
179
    public function whereNotBetweenTime(string $field, $startTime, $endTime)
180
    {
181
        return $this->whereTime($field, '<', $startTime)
182
            ->whereTime($field, '>', $endTime);
183
    }
184
185
    /**
186
     * 查询当前时间在两个时间字段范围 whereBetweenTimeField('start_time', 'end_time')
187
     * @access public
188
     * @param string $startField 开始时间字段
189
     * @param string $endField   结束时间字段
190
     * @return $this
191
     */
192
    public function whereBetweenTimeField(string $startField, string $endField)
193
    {
194
        return $this->whereTime($startField, '<=', time())
195
            ->whereTime($endField, '>=', time());
196
    }
197
198
    /**
199
     * 查询当前时间不在两个时间字段范围 whereNotBetweenTimeField('start_time', 'end_time')
200
     * @access public
201
     * @param string $startField 开始时间字段
202
     * @param string $endField   结束时间字段
203
     * @return $this
204
     */
205
    public function whereNotBetweenTimeField(string $startField, string $endField)
206
    {
207
        return $this->whereTime($startField, '>', time())
208
            ->whereTime($endField, '<', time(), 'OR');
209
    }
210
211
}
212