|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* @file TimeHelper.php |
|
5
|
|
|
* @brief This file contains the TimeHelper class. |
|
6
|
|
|
* @details |
|
7
|
|
|
* @author Filippo F. Fadda |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
|
|
11
|
|
|
namespace ToolBag\Helper; |
|
12
|
|
|
|
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* @brief This class contains routines to handle time. |
|
16
|
|
|
* @nosubgrouping |
|
17
|
|
|
*/ |
|
18
|
|
|
class TimeHelper { |
|
19
|
|
|
|
|
20
|
|
|
/** @name Time Periods */ |
|
21
|
|
|
//!@{ |
|
22
|
|
|
const TODAY = "today"; |
|
23
|
|
|
const YESTERDAY = "yesterday"; |
|
24
|
|
|
const THIS_WEEK = "this-week"; |
|
25
|
|
|
const LAST_WEEK = "last-week"; |
|
26
|
|
|
const THIS_MONTH = "this-month"; |
|
27
|
|
|
const LAST_MONTH = "last-month"; |
|
28
|
|
|
const THIS_YEAR = "this-year"; |
|
29
|
|
|
const LAST_YEAR = "last-year"; |
|
30
|
|
|
const ALL_TIME = "all-time"; |
|
31
|
|
|
//!@} |
|
32
|
|
|
|
|
33
|
|
|
|
|
34
|
|
|
/** @name Time Periods Array */ |
|
35
|
|
|
//!@{ |
|
36
|
|
|
public static $periods = array( // Cannot use [] syntax otherwise Doxygen generates a warning. |
|
37
|
|
|
self::ALL_TIME => NULL, |
|
38
|
|
|
self::THIS_YEAR => NULL, |
|
39
|
|
|
self::LAST_YEAR => NULL, |
|
40
|
|
|
self::THIS_MONTH => NULL, |
|
41
|
|
|
self::LAST_MONTH => NULL, |
|
42
|
|
|
self::THIS_WEEK => NULL, |
|
43
|
|
|
self::LAST_WEEK => NULL, |
|
44
|
|
|
self::TODAY => NULL, |
|
45
|
|
|
self::YESTERDAY => NULL |
|
46
|
|
|
); |
|
47
|
|
|
//!@} |
|
48
|
|
|
|
|
49
|
|
|
|
|
50
|
|
|
/** |
|
51
|
|
|
* @brief Returns an associative array with the elapsed time, from the provided timestamp, in days, hours, minutes and |
|
52
|
|
|
* seconds. |
|
53
|
|
|
* @param string $timestamp A timestamp in seconds/microseconds. |
|
54
|
|
|
* @param string $micro When `true` the timestamp is expressed in microseconds otherwise in seconds. |
|
55
|
|
|
* @return array An associative array |
|
56
|
|
|
*/ |
|
57
|
|
|
public static function since($timestamp, $micro = FALSE) { |
|
58
|
|
|
$microsecondsInASecond = 1000000; |
|
59
|
|
|
$secondsInAMinute = 60; |
|
60
|
|
|
$secondsInAnHour = 60 * $secondsInAMinute; |
|
61
|
|
|
$secondsInADay = 24 * $secondsInAnHour; |
|
62
|
|
|
|
|
63
|
|
|
if ($micro) { |
|
|
|
|
|
|
64
|
|
|
// Gets the current timestamp in microseconds. |
|
65
|
|
|
$now = microtime(TRUE); |
|
66
|
|
|
|
|
67
|
|
|
// Subtracts from the current timestamp the last timestamp server was started. |
|
68
|
|
|
$microseconds = ($now * $microsecondsInASecond) - (float)$timestamp; |
|
69
|
|
|
|
|
70
|
|
|
// Converts microseconds in seconds. |
|
71
|
|
|
$seconds = floor($microseconds / $microsecondsInASecond); |
|
72
|
|
|
} |
|
73
|
|
|
else { |
|
74
|
|
|
// Calculates difference in seconds. |
|
75
|
|
|
$seconds = time() - $timestamp; |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
// Extracts days. |
|
79
|
|
|
$days = (int)floor($seconds / $secondsInADay); |
|
80
|
|
|
|
|
81
|
|
|
// Extracts hours. |
|
82
|
|
|
$hourSeconds = $seconds % $secondsInADay; |
|
83
|
|
|
$hours = (int)floor($hourSeconds / $secondsInAnHour); |
|
84
|
|
|
|
|
85
|
|
|
// Extracts minutes. |
|
86
|
|
|
$minuteSeconds = $hourSeconds % $secondsInAnHour; |
|
87
|
|
|
$minutes = (int)floor($minuteSeconds / $secondsInAMinute); |
|
88
|
|
|
|
|
89
|
|
|
// Extracts the remaining seconds. |
|
90
|
|
|
$remainingSeconds = $minuteSeconds % $secondsInAMinute; |
|
91
|
|
|
$seconds = (int)ceil($remainingSeconds); |
|
92
|
|
|
|
|
93
|
|
|
$time = []; |
|
94
|
|
|
$time['days'] = $days; |
|
95
|
|
|
$time['hours'] = $hours; |
|
96
|
|
|
$time['minutes'] = $minutes; |
|
97
|
|
|
$time['seconds'] = $seconds; |
|
98
|
|
|
|
|
99
|
|
|
return $time; |
|
100
|
|
|
} |
|
101
|
|
|
|
|
102
|
|
|
|
|
103
|
|
|
/** |
|
104
|
|
|
* @brief Checks if the provided string represents a period of time and returns it if exists otherwise returns `false`. |
|
105
|
|
|
* @param string $str A human readable period of time. |
|
106
|
|
|
* @return int|bool If the period of time exists returns it, else returns `false`. In case `$str` is `null`, returns |
|
107
|
|
|
* `all_time`. |
|
108
|
|
|
*/ |
|
109
|
|
|
public static function period($str) { |
|
110
|
|
|
return is_null($str) ? self::ALL_TIME : ArrayHelper::key($str, self::$periods); |
|
|
|
|
|
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* @brief Returns a measure of the time passed since the provided timestamp. In case is passed more than a day, |
|
116
|
|
|
* returns a human readable date. |
|
117
|
|
|
* @param int $timestamp A timestamp in seconds. |
|
118
|
|
|
* @param bool $showTime When `true` returns also the time passed in case of an event occurred in the past. |
|
119
|
|
|
* @return string |
|
120
|
|
|
*/ |
|
121
|
|
|
public static function when($timestamp, $showTime = TRUE) { |
|
122
|
|
|
$today = date('Ymd'); |
|
123
|
|
|
|
|
124
|
|
|
// Today. |
|
125
|
|
|
if ($today == date('Ymd', $timestamp)) { |
|
126
|
|
|
$time = self::since($timestamp); |
|
127
|
|
|
|
|
128
|
|
|
if ($time['hours'] > 1) |
|
129
|
|
|
return sprintf('%d hours ago', $time['hours']); |
|
130
|
|
|
elseif ($time['hours'] == 1) |
|
131
|
|
|
return "one hour ago"; |
|
132
|
|
|
elseif ($time['minutes'] > 1) |
|
133
|
|
|
return sprintf('%d minutes ago', $time['minutes']); |
|
134
|
|
|
elseif ($time['minutes'] == 1) |
|
135
|
|
|
return "one minute ago"; |
|
136
|
|
|
elseif ($time['seconds'] > 1) |
|
137
|
|
|
return sprintf('%d seconds ago', $time['seconds']); |
|
138
|
|
|
else // $time['seconds'] == 1 |
|
139
|
|
|
return "one second ago"; |
|
140
|
|
|
} |
|
141
|
|
|
// Yesterday. |
|
142
|
|
|
elseif (strtotime('-1 day', $today) == date('Ymd', $timestamp)) |
|
|
|
|
|
|
143
|
|
|
return "yesterday"; |
|
144
|
|
|
// In the past. |
|
145
|
|
|
else |
|
146
|
|
|
return $showTime ? date('d/m/Y H:i', $timestamp) : date('d/m/Y', $timestamp); |
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
|
|
150
|
|
|
/** |
|
151
|
|
|
* @brief Given a constant representing a period, returns a formatted string. |
|
152
|
|
|
* @param int $periodInTime A period in time. |
|
153
|
|
|
* @param string $prefix A string prefix. |
|
154
|
|
|
* @param string $postfix A string postfix. |
|
155
|
|
|
* @return string |
|
156
|
|
|
*/ |
|
157
|
|
|
public static function aWhileBack($periodInTime, $prefix = "", $postfix = "") { |
|
158
|
|
|
$date = new \DateTime(); |
|
159
|
|
|
|
|
160
|
|
|
switch ($periodInTime) { |
|
161
|
|
|
case self::TODAY: |
|
162
|
|
|
$format = $date->format("Ymd"); |
|
163
|
|
|
break; |
|
164
|
|
|
case self::YESTERDAY: |
|
165
|
|
|
$date->modify('yesterday'); |
|
166
|
|
|
$format = $date->format("Ymd"); |
|
167
|
|
|
break; |
|
168
|
|
|
case self::THIS_WEEK: |
|
169
|
|
|
$format = $date->format("Y_W"); |
|
170
|
|
|
break; |
|
171
|
|
|
case self::LAST_WEEK; |
|
172
|
|
|
$date->modify('last week'); |
|
173
|
|
|
$format = $date->format("Y_W"); |
|
174
|
|
|
break; |
|
175
|
|
|
case self::THIS_MONTH; |
|
176
|
|
|
$format = $date->format("Ym"); |
|
177
|
|
|
break; |
|
178
|
|
|
case self::LAST_MONTH; |
|
179
|
|
|
$date->modify('last month'); |
|
180
|
|
|
$format = $date->format("Ym"); |
|
181
|
|
|
break; |
|
182
|
|
|
case self::THIS_YEAR; |
|
183
|
|
|
$format = $date->format("Y"); |
|
184
|
|
|
break; |
|
185
|
|
|
case self::LAST_YEAR: |
|
186
|
|
|
$date->modify('last year'); |
|
187
|
|
|
$format = $date->format("Y"); |
|
188
|
|
|
break; |
|
189
|
|
|
default: // EVER |
|
190
|
|
|
$format = ""; |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
return empty($format) ? $format : $prefix.$format.$postfix; |
|
|
|
|
|
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
|
|
197
|
|
|
/** |
|
198
|
|
|
* @brief Given a constant representing a period, returns a range of timestamps (minimum and maximum) for that period. |
|
199
|
|
|
* @param int $periodInTime A period in time. |
|
200
|
|
|
* @param[out] \DateTime $minTimestamp The minimum date in the period. |
|
201
|
|
|
* @param[out] \DateTime $maxTimestamp The maximum date in the period. |
|
202
|
|
|
*/ |
|
203
|
|
|
public static function minMaxInPeriod($periodInTime, &$minTimestamp, &$maxTimestamp) { |
|
204
|
|
|
switch ($periodInTime) { |
|
205
|
|
|
case self::TODAY: |
|
206
|
|
|
$minTimestamp = strtotime('midnight'); |
|
207
|
|
|
$maxTimestamp = time(); |
|
208
|
|
|
break; |
|
209
|
|
|
case self::YESTERDAY: |
|
210
|
|
|
$minTimestamp = strtotime('yesterday'); |
|
211
|
|
|
$maxTimestamp = strtotime('midnight') - 1; |
|
212
|
|
|
break; |
|
213
|
|
|
case self::THIS_WEEK: |
|
214
|
|
|
$minTimestamp = strtotime('last monday'); |
|
215
|
|
|
$maxTimestamp = time(); |
|
216
|
|
|
break; |
|
217
|
|
|
case self::LAST_WEEK; |
|
218
|
|
|
$minTimestamp = strtotime('Monday last week'); |
|
219
|
|
|
$maxTimestamp = strtotime('Monday this week') - 1; |
|
220
|
|
|
break; |
|
221
|
|
|
case self::THIS_MONTH; |
|
222
|
|
|
$minTimestamp = strtotime('first day of this month midnight'); |
|
223
|
|
|
$maxTimestamp = time(); |
|
224
|
|
|
break; |
|
225
|
|
|
case self::LAST_MONTH; |
|
226
|
|
|
$minTimestamp = strtotime('first day of last month midnight'); |
|
227
|
|
|
$maxTimestamp = strtotime('first day of this month midnight') - 1; |
|
228
|
|
|
break; |
|
229
|
|
|
case self::THIS_YEAR; |
|
230
|
|
|
$minTimestamp = strtotime('first day of January midnight'); |
|
231
|
|
|
$maxTimestamp = time(); |
|
232
|
|
|
break; |
|
233
|
|
|
case self::LAST_YEAR: |
|
234
|
|
|
$minTimestamp = strtotime('first day of January last year midnight'); |
|
235
|
|
|
$maxTimestamp = strtotime('first day of January this year midnight') - 1; |
|
236
|
|
|
break; |
|
237
|
|
|
default: // EVER |
|
238
|
|
|
$minTimestamp = 0; |
|
239
|
|
|
$maxTimestamp = new \stdClass(); |
|
240
|
|
|
} |
|
241
|
|
|
} |
|
242
|
|
|
|
|
243
|
|
|
|
|
244
|
|
|
/** |
|
245
|
|
|
* @brief Given a period of time (an year, a month or a day), calculates the date limits for that period. |
|
246
|
|
|
* @param[out] \DateTime $minDate The minimum date in the period. |
|
247
|
|
|
* @param[out] \DateTime $maxDate The maximum date in the period. |
|
248
|
|
|
* @param string $year An year. |
|
249
|
|
|
* @param string $month (optional) A month. |
|
250
|
|
|
* @param string $day (optional) A day. |
|
251
|
|
|
*/ |
|
252
|
|
|
public static function dateLimits(&$minDate, &$maxDate, $year, $month = NULL, $day = NULL) { |
|
253
|
|
|
$aDay = (is_null($day)) ? 1 : (int)$day; |
|
254
|
|
|
$aMonth = (is_null($month)) ? 1 : (int)$month; |
|
255
|
|
|
$aYear = (int)$year; |
|
256
|
|
|
|
|
257
|
|
|
$minDate = (new \DateTime())->setDate($aYear, $aMonth, $aDay)->modify('midnight'); |
|
258
|
|
|
$maxDate = clone($minDate); |
|
259
|
|
|
|
|
260
|
|
|
if (isset($day)) |
|
261
|
|
|
$maxDate->modify('tomorrow')->modify('last second'); |
|
262
|
|
|
elseif (isset($month)) |
|
263
|
|
|
$maxDate->modify('last day of this month')->modify('last second'); |
|
264
|
|
|
else |
|
265
|
|
|
$maxDate->setDate($aYear, 12, 31)->modify('last second'); |
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
} |
In PHP, under loose comparison (like
==, or!=, orswitchconditions), values of different types might be equal.For
stringvalues, the empty string''is a special case, in particular the following results might be unexpected: