|
1
|
|
|
<?php |
|
2
|
|
|
namespace Fwlib\Util\Common; |
|
3
|
|
|
|
|
4
|
|
|
/** |
|
5
|
|
|
* Datetime util |
|
6
|
|
|
* |
|
7
|
|
|
* @copyright Copyright 2009-2015 Fwolf |
|
8
|
|
|
* @license http://www.gnu.org/licenses/lgpl.html LGPL-3.0+ |
|
9
|
|
|
*/ |
|
10
|
|
|
class DatetimeUtil |
|
11
|
|
|
{ |
|
12
|
|
|
/** |
|
13
|
|
|
* Symbol of Time unit |
|
14
|
|
|
* |
|
15
|
|
|
* @var array |
|
16
|
|
|
*/ |
|
17
|
|
|
protected $timeUnitSymbol = [ |
|
18
|
|
|
'sec' => 's', |
|
19
|
|
|
'second' => 's', |
|
20
|
|
|
'seconds' => 's', |
|
21
|
|
|
'min' => 'i', |
|
22
|
|
|
'minute' => 'i', |
|
23
|
|
|
'minutes' => 'i', |
|
24
|
|
|
'hour' => 'h', |
|
25
|
|
|
'hours' => 'h', |
|
26
|
|
|
'day' => 'd', |
|
27
|
|
|
'days' => 'd', |
|
28
|
|
|
'week' => 'w', |
|
29
|
|
|
'weeks' => 'w', |
|
30
|
|
|
'month' => 'm', |
|
31
|
|
|
'months' => 'm', |
|
32
|
|
|
'year' => 'y', |
|
33
|
|
|
'years' => 'y', |
|
34
|
|
|
'century' => 'c', |
|
35
|
|
|
'centuries' => 'c', |
|
36
|
|
|
]; |
|
37
|
|
|
|
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* How many seconds a time unit equals |
|
41
|
|
|
* |
|
42
|
|
|
* @var array |
|
43
|
|
|
*/ |
|
44
|
|
|
protected $timeUnitWeight = [ |
|
45
|
|
|
's' => 1, |
|
46
|
|
|
'i' => 60, |
|
47
|
|
|
'h' => 3600, |
|
48
|
|
|
'd' => 86400, |
|
49
|
|
|
'w' => 604800, |
|
50
|
|
|
'm' => 2592000, |
|
51
|
|
|
'y' => 31536000, |
|
52
|
|
|
'c' => 3153600000, |
|
53
|
|
|
]; |
|
54
|
|
|
|
|
55
|
|
|
|
|
56
|
|
|
/** |
|
57
|
|
|
* Convert second back to string description. |
|
58
|
|
|
* |
|
59
|
|
|
* No week and month in result, Because 12m != 1y, it can't convert month |
|
60
|
|
|
* and year by solid ratio, so do week. |
|
61
|
|
|
* |
|
62
|
|
|
* One year are 365 days, no consider of 366 days, because it did not know |
|
63
|
|
|
* which year it is. |
|
64
|
|
|
* |
|
65
|
|
|
* @param int $second |
|
66
|
|
|
* @param boolean $useSimpleUnit Use y instead of full word year. |
|
67
|
|
|
* @return string |
|
68
|
|
|
*/ |
|
69
|
|
|
public function convertSecondToString($second, $useSimpleUnit = true) |
|
70
|
|
|
{ |
|
71
|
|
|
if (empty($second) || !is_numeric($second)) { |
|
72
|
|
|
return ''; |
|
73
|
|
|
} |
|
74
|
|
|
|
|
75
|
|
|
$unitDict = [ |
|
76
|
|
|
['c', -1, 'century', 'centuries'], |
|
77
|
|
|
['y', 100, 'year', 'years'], |
|
78
|
|
|
['d', 365, 'day', 'days'], |
|
79
|
|
|
['h', 24, 'hour', 'hours'], |
|
80
|
|
|
['i', 60, 'minute', 'minutes'], |
|
81
|
|
|
['s', 60, 'second', 'seconds'], |
|
82
|
|
|
]; |
|
83
|
|
|
|
|
84
|
|
|
// Loop from smallest unit |
|
85
|
|
|
$i = count($unitDict); |
|
86
|
|
|
$result = ''; |
|
87
|
|
|
while (0 < $i && 0 < $second) { |
|
88
|
|
|
$i --; |
|
89
|
|
|
// $i is index of current unit now |
|
90
|
|
|
|
|
91
|
|
|
// Reach top level, end loop |
|
92
|
|
|
if (-1 == $unitDict[$i][1]) { |
|
93
|
|
|
$unitIndex = ($useSimpleUnit) ? 0 |
|
94
|
|
|
: ((1 == $second) ? 2 : 3); |
|
95
|
|
|
|
|
96
|
|
|
$result = $second . $unitDict[$i][$unitIndex] . ' ' . $result; |
|
97
|
|
|
break; |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
$j = $second % $unitDict[$i][1]; |
|
101
|
|
|
if (0 != $j) { |
|
102
|
|
|
$unitIndex = ($useSimpleUnit) ? 0 |
|
103
|
|
|
: ((1 == $second) ? 2 : 3); |
|
104
|
|
|
|
|
105
|
|
|
$result = $j . $unitDict[$i][$unitIndex] . ' ' . $result; |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
$second = floor($second / $unitDict[$i][1]); |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
return rtrim($result); |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* Convert string to seconds it means |
|
117
|
|
|
* |
|
118
|
|
|
* Month and week are allowed here, with solid conversion ratio: |
|
119
|
|
|
* |
|
120
|
|
|
* 1month = 30days |
|
121
|
|
|
* 1week = 7days |
|
122
|
|
|
* |
|
123
|
|
|
* One year equals 365days, same with covertSecondToString(). |
|
124
|
|
|
* |
|
125
|
|
|
* @param string $string |
|
126
|
|
|
* @return integer |
|
127
|
|
|
*/ |
|
128
|
|
|
public function convertStringToSecond($string) |
|
129
|
|
|
{ |
|
130
|
|
|
if (empty($string)) { |
|
131
|
|
|
return 0; |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
// All number, return directly |
|
135
|
|
|
if (is_numeric($string)) { |
|
136
|
|
|
return $string; |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
// Replace time unit word with symbol(single letter) |
|
140
|
|
|
$string = strtolower($string); |
|
141
|
|
|
$string = strtr($string, $this->timeUnitSymbol); |
|
142
|
|
|
|
|
143
|
|
|
/** @noinspection SpellCheckingInspection */ |
|
144
|
|
|
$i = preg_match_all('/([+-]?\s*)(\d+)([cymwdhis])/', $string, $match); |
|
145
|
|
|
if (0 < $i) { |
|
146
|
|
|
$second = 0; |
|
147
|
|
|
foreach ($match[0] as $key => $value) { |
|
148
|
|
|
if ('-' == trim($match[1][$key])) { |
|
149
|
|
|
$second -= $match[2][$key] * |
|
150
|
|
|
$this->timeUnitWeight[$match[3][$key]]; |
|
151
|
|
|
|
|
152
|
|
|
} else { |
|
153
|
|
|
$second += $match[2][$key] * |
|
154
|
|
|
$this->timeUnitWeight[$match[3][$key]]; |
|
155
|
|
|
} |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
return $second; |
|
159
|
|
|
|
|
160
|
|
|
} else { |
|
161
|
|
|
return 0; |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
return $second; |
|
|
|
|
|
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
|
|
168
|
|
|
/** |
|
169
|
|
|
* Convert sybase time to normal |
|
170
|
|
|
* |
|
171
|
|
|
* Sybase's time end with ':000', probably because using dblib. |
|
172
|
|
|
* |
|
173
|
|
|
* @param string $time |
|
174
|
|
|
* @return integer |
|
175
|
|
|
*/ |
|
176
|
|
|
public function convertTimeFromSybase($time) |
|
177
|
|
|
{ |
|
178
|
|
|
if (!empty($time)) { |
|
179
|
|
|
// Remove tail add by sybase |
|
180
|
|
|
$time = preg_replace('/:\d{3}/', '', $time); |
|
181
|
|
|
} |
|
182
|
|
|
return strtotime($time); |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
|
|
186
|
|
|
/** |
|
187
|
|
|
* Get time with seconds.microseconds format |
|
188
|
|
|
* |
|
189
|
|
|
* The result comes from float value, but is string format, length: 10.8. |
|
190
|
|
|
* |
|
191
|
|
|
* @return string |
|
192
|
|
|
*/ |
|
193
|
|
|
public function getMicroTime() |
|
194
|
|
|
{ |
|
195
|
|
|
list($msec, $sec) = explode(' ', microtime()); |
|
196
|
|
|
|
|
197
|
|
|
return $sec . substr($msec, 1); |
|
198
|
|
|
} |
|
199
|
|
|
} |
|
200
|
|
|
|
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return,dieorexitstatements that have been added for debug purposes.In the above example, the last
return falsewill never be executed, because a return statement has already been met in every possible execution path.