Rozbo /
puck
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Created by rozbo at 2017/3/16 上午11:09 |
||
| 4 | */ |
||
| 5 | |||
| 6 | namespace puck\helpers; |
||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | class TimeAgo |
||
| 11 | { |
||
| 12 | // defines the number of seconds per "unit" |
||
| 13 | private $secondsPerMinute = 60; |
||
| 14 | private $secondsPerHour = 3600; |
||
| 15 | private $secondsPerDay = 86400; |
||
| 16 | private $secondsPerMonth = 2592000; |
||
| 17 | private $secondsPerYear = 31536000; // 31622400 seconds on leap years though... |
||
| 18 | private $timezone; |
||
| 19 | private $previousTimezone; |
||
| 20 | |||
| 21 | private static $timeAgoStrings = array( |
||
| 22 | 'aboutOneDay' => "1 天前", |
||
| 23 | 'aboutOneHour' => "大约 1 小时前", |
||
| 24 | 'aboutOneMonth' => "大约 1 个月前", |
||
| 25 | 'aboutOneYear' => "大约 1 年前", |
||
| 26 | 'days' => "%s 天前", |
||
| 27 | 'hours' => "%s 小时前", |
||
| 28 | 'lessThanAMinute' => "1 分钟内", |
||
| 29 | 'lessThanOneHour' => "%s 分钟前", |
||
| 30 | 'months' => "%s 个月前", |
||
| 31 | 'oneMinute' => "1 分钟前", |
||
| 32 | 'years' => "超过 %s 年前" |
||
| 33 | ); |
||
| 34 | |||
| 35 | /** |
||
| 36 | * TimeAgo constructor. |
||
| 37 | * @param null|DateTimeZone $timezone the timezone to use (uses system if none is given) |
||
| 38 | */ |
||
| 39 | public function __construct($timezone = null) |
||
| 40 | { |
||
| 41 | $this->timezone = $timezone; |
||
| 42 | // sets the default timezone |
||
| 43 | $this->changeTimezone(); |
||
| 44 | } |
||
| 45 | |||
| 46 | /** |
||
| 47 | * 析构函数用来恢复时区 |
||
| 48 | */ |
||
| 49 | public function __destruct() { |
||
| 50 | $this->restoreTimezone(); |
||
| 51 | } |
||
| 52 | |||
| 53 | public function inStamp($past, $now = null) { |
||
| 54 | if($now==null){ |
||
| 55 | $now=time(); |
||
| 56 | } |
||
| 57 | // creates the "time ago" string. This always starts with an "about..." |
||
| 58 | $timeAgo = ""; |
||
|
0 ignored issues
–
show
|
|||
| 59 | |||
| 60 | // finds the time difference |
||
| 61 | $timeDifference = $now - $past; |
||
| 62 | // rule 0 |
||
| 63 | // $past is null or empty or '' |
||
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
43% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. Loading history...
|
|||
| 64 | if ($past==0) { |
||
| 65 | $timeAgo = $this->translate('never'); |
||
| 66 | } |
||
| 67 | // rule 1 |
||
| 68 | // less than 29secs |
||
| 69 | else if ($this->isLessThan29Seconds($timeDifference)) { |
||
| 70 | $timeAgo = $this->translate('lessThanAMinute'); |
||
| 71 | } |
||
| 72 | // rule 2 |
||
| 73 | // more than 29secs and less than 1min29secss |
||
| 74 | else if ($this->isLessThan1Min29Seconds($timeDifference)) { |
||
| 75 | $timeAgo = $this->translate('oneMinute'); |
||
| 76 | } |
||
| 77 | // rule 3 |
||
| 78 | // between 1min30secs and 44mins29secs |
||
| 79 | else if ($this->isLessThan44Min29Secs($timeDifference)) { |
||
| 80 | $minutes = round($timeDifference / $this->secondsPerMinute); |
||
| 81 | $timeAgo = $this->translate('lessThanOneHour', $minutes); |
||
| 82 | } |
||
| 83 | // rule 4 |
||
| 84 | // between 44mins30secs and 1hour29mins59secs |
||
| 85 | else if ($this->isLessThan1Hour29Mins59Seconds($timeDifference)) { |
||
| 86 | $timeAgo = $this->translate('aboutOneHour'); |
||
| 87 | } |
||
| 88 | // rule 5 |
||
| 89 | // between 1hour29mins59secs and 23hours59mins29secs |
||
| 90 | else if ($this->isLessThan23Hours59Mins29Seconds($timeDifference)) { |
||
| 91 | $hours = round($timeDifference / $this->secondsPerHour); |
||
| 92 | $timeAgo = $this->translate('hours', $hours); |
||
| 93 | } |
||
| 94 | // rule 6 |
||
| 95 | // between 23hours59mins30secs and 47hours59mins29secs |
||
| 96 | else if ($this->isLessThan47Hours59Mins29Seconds($timeDifference)) { |
||
| 97 | $timeAgo = $this->translate('aboutOneDay'); |
||
| 98 | } |
||
| 99 | // rule 7 |
||
| 100 | // between 47hours59mins30secs and 29days23hours59mins29secs |
||
| 101 | else if ($this->isLessThan29Days23Hours59Mins29Seconds($timeDifference)) { |
||
| 102 | $days = round($timeDifference / $this->secondsPerDay); |
||
| 103 | $timeAgo = $this->translate('days', $days); |
||
| 104 | } |
||
| 105 | // rule 8 |
||
| 106 | // between 29days23hours59mins30secs and 59days23hours59mins29secs |
||
| 107 | else if ($this->isLessThan59Days23Hours59Mins29Secs($timeDifference)) { |
||
| 108 | $timeAgo = $this->translate('aboutOneMonth'); |
||
| 109 | } |
||
| 110 | // rule 9 |
||
| 111 | // between 59days23hours59mins30secs and 1year (minus 1sec) |
||
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
36% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. Loading history...
|
|||
| 112 | else if ($this->isLessThan1Year($timeDifference)) { |
||
| 113 | $months = round($timeDifference / $this->secondsPerMonth); |
||
| 114 | // if months is 1, then set it to 2, because we are "past" 1 month |
||
| 115 | if ($months == 1) { |
||
| 116 | $months = 2; |
||
| 117 | } |
||
| 118 | |||
| 119 | $timeAgo = $this->translate('months', $months); |
||
| 120 | } |
||
| 121 | // rule 10 |
||
| 122 | // between 1year and 2years (minus 1sec) |
||
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
36% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. Loading history...
|
|||
| 123 | else if ($this->isLessThan2Years($timeDifference)) { |
||
| 124 | $timeAgo = $this->translate('aboutOneYear'); |
||
| 125 | } |
||
| 126 | // rule 11 |
||
| 127 | // 2years or more |
||
| 128 | else { |
||
| 129 | $years = floor($timeDifference / $this->secondsPerYear); |
||
| 130 | $timeAgo = $this->translate('years', $years); |
||
| 131 | } |
||
| 132 | |||
| 133 | return $timeAgo; |
||
| 134 | } |
||
| 135 | /** |
||
| 136 | * Fetches the different between $past and $now in a spoken format. |
||
| 137 | * NOTE: both past and now should be parseable by strtotime |
||
| 138 | * @param string $past the past date to use |
||
| 139 | * @param string $now the current time, defaults to now (can be an other time though) |
||
| 140 | * @return string the difference in spoken format, e.g. 1 day ago |
||
| 141 | */ |
||
| 142 | public function inWords($past, $now = "now") |
||
| 143 | { |
||
| 144 | |||
| 145 | // finds the past in datetime |
||
| 146 | $past = strtotime($past); |
||
| 147 | // finds the current datetime |
||
| 148 | $now = strtotime($now); |
||
| 149 | if ($this->isPastEmpty($past)) { |
||
| 150 | $past=0; |
||
|
0 ignored issues
–
show
$past is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the Loading history...
|
|||
| 151 | $past=0; |
||
| 152 | } |
||
| 153 | return $this->inStamp($past,$now); |
||
| 154 | } |
||
| 155 | |||
| 156 | /** |
||
| 157 | * Fetches the date difference between the two given dates. |
||
| 158 | * NOTE: both past and now should be parseable by strtotime |
||
| 159 | * |
||
| 160 | * @param string $past the "past" time to parse |
||
| 161 | * @param string $now the "now" time to parse |
||
| 162 | * @return array the difference in dates, using the two dates |
||
| 163 | */ |
||
| 164 | public function dateDifference($past, $now = "now") |
||
| 165 | { |
||
| 166 | // initializes the placeholders for the different "times" |
||
| 167 | $seconds = 0; |
||
| 168 | $minutes = 0; |
||
| 169 | $hours = 0; |
||
| 170 | $days = 0; |
||
| 171 | $months = 0; |
||
| 172 | $years = 0; |
||
| 173 | |||
| 174 | // finds the past in datetime |
||
| 175 | $past = strtotime($past); |
||
| 176 | // finds the current datetime |
||
| 177 | $now = strtotime($now); |
||
| 178 | |||
| 179 | // calculates the difference |
||
| 180 | $timeDifference = $now - $past; |
||
| 181 | |||
| 182 | // starts determining the time difference |
||
| 183 | if ($timeDifference >= 0) { |
||
| 184 | switch ($timeDifference) { |
||
| 185 | // finds the number of years |
||
| 186 | case ($timeDifference >= $this->secondsPerYear): |
||
| 187 | // uses floor to remove decimals |
||
| 188 | $years = floor($timeDifference / $this->secondsPerYear); |
||
| 189 | // saves the amount of seconds left |
||
| 190 | $timeDifference = $timeDifference - ($years * $this->secondsPerYear); |
||
| 191 | |||
| 192 | // finds the number of months |
||
| 193 | case ($timeDifference >= $this->secondsPerMonth && $timeDifference <= ($this->secondsPerYear - 1)): |
||
| 194 | // uses floor to remove decimals |
||
| 195 | $months = floor($timeDifference / $this->secondsPerMonth); |
||
| 196 | // saves the amount of seconds left |
||
| 197 | $timeDifference = $timeDifference - ($months * $this->secondsPerMonth); |
||
| 198 | |||
| 199 | // finds the number of days |
||
| 200 | case ($timeDifference >= $this->secondsPerDay && $timeDifference <= ($this->secondsPerYear - 1)): |
||
| 201 | // uses floor to remove decimals |
||
| 202 | $days = floor($timeDifference / $this->secondsPerDay); |
||
| 203 | // saves the amount of seconds left |
||
| 204 | $timeDifference = $timeDifference - ($days * $this->secondsPerDay); |
||
| 205 | |||
| 206 | // finds the number of hours |
||
| 207 | case ($timeDifference >= $this->secondsPerHour && $timeDifference <= ($this->secondsPerDay - 1)): |
||
| 208 | // uses floor to remove decimals |
||
| 209 | $hours = floor($timeDifference / $this->secondsPerHour); |
||
| 210 | // saves the amount of seconds left |
||
| 211 | $timeDifference = $timeDifference - ($hours * $this->secondsPerHour); |
||
| 212 | |||
| 213 | // finds the number of minutes |
||
| 214 | case ($timeDifference >= $this->secondsPerMinute && $timeDifference <= ($this->secondsPerHour - 1)): |
||
| 215 | // uses floor to remove decimals |
||
| 216 | $minutes = floor($timeDifference / $this->secondsPerMinute); |
||
| 217 | // saves the amount of seconds left |
||
| 218 | $timeDifference = $timeDifference - ($minutes * $this->secondsPerMinute); |
||
| 219 | |||
| 220 | // finds the number of seconds |
||
| 221 | case ($timeDifference <= ($this->secondsPerMinute - 1)): |
||
| 222 | // seconds is just what there is in the timeDifference variable |
||
| 223 | $seconds = $timeDifference; |
||
| 224 | } |
||
| 225 | } |
||
| 226 | |||
| 227 | $difference = [ |
||
| 228 | "years" => $years, |
||
| 229 | "months" => $months, |
||
| 230 | "days" => $days, |
||
| 231 | "hours" => $hours, |
||
| 232 | "minutes" => $minutes, |
||
| 233 | "seconds" => $seconds, |
||
| 234 | ]; |
||
| 235 | |||
| 236 | return $difference; |
||
| 237 | } |
||
| 238 | |||
| 239 | /** |
||
| 240 | * Translates the given $label, and adds the given $time. |
||
| 241 | * @param string $label the label to translate |
||
| 242 | * @param string $time the time to add to the translated text. |
||
| 243 | * @return string the translated label text including the time. |
||
| 244 | */ |
||
| 245 | protected function translate($label, $time = '') |
||
| 246 | { |
||
| 247 | // handles a usecase introduced in #18, where a new translation was added. |
||
| 248 | // This would cause an array-out-of-bound exception, since the index does not |
||
| 249 | // exist in most translations. |
||
| 250 | if (!isset(self::$timeAgoStrings[$label])) { |
||
| 251 | return ''; |
||
| 252 | } |
||
| 253 | |||
| 254 | return sprintf(self::$timeAgoStrings[$label], $time); |
||
| 255 | } |
||
| 256 | |||
| 257 | |||
| 258 | /** |
||
| 259 | * Changes the timezone |
||
| 260 | */ |
||
| 261 | protected function changeTimezone() |
||
| 262 | { |
||
| 263 | $this->previousTimezone = false; |
||
| 264 | if ($this->timezone) { |
||
| 265 | $this->previousTimezone = date_default_timezone_get(); |
||
| 266 | date_default_timezone_set($this->timezone); |
||
| 267 | } |
||
| 268 | } |
||
| 269 | |||
| 270 | /** |
||
| 271 | * Restores a previous timezone |
||
| 272 | */ |
||
| 273 | protected function restoreTimezone() |
||
| 274 | { |
||
| 275 | if ($this->previousTimezone) { |
||
|
0 ignored issues
–
show
The expression
$this->previousTimezone of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
| 276 | date_default_timezone_set($this->previousTimezone); |
||
| 277 | $this->previousTimezone = false; |
||
| 278 | } |
||
| 279 | } |
||
| 280 | |||
| 281 | /** |
||
| 282 | * Checks if the given past is empty |
||
| 283 | * @param string $past the "past" to check |
||
| 284 | * @return bool true if empty, else false |
||
| 285 | */ |
||
| 286 | private function isPastEmpty($past) |
||
| 287 | { |
||
| 288 | return $past === '' || is_null($past) || empty($past); |
||
| 289 | } |
||
| 290 | |||
| 291 | /** |
||
| 292 | * Checks if the time difference is less than 29seconds |
||
| 293 | * @param int $timeDifference the time difference in seconds |
||
| 294 | * @return bool |
||
| 295 | */ |
||
| 296 | private function isLessThan29Seconds($timeDifference) |
||
| 297 | { |
||
| 298 | return $timeDifference <= 29; |
||
| 299 | } |
||
| 300 | |||
| 301 | /** |
||
| 302 | * Checks if the time difference is less than 1min 29seconds |
||
| 303 | * @param int $timeDifference the time difference in seconds |
||
| 304 | * @return bool |
||
| 305 | */ |
||
| 306 | private function isLessThan1Min29Seconds($timeDifference) |
||
| 307 | { |
||
| 308 | return $timeDifference >= 30 && $timeDifference <= 89; |
||
| 309 | } |
||
| 310 | |||
| 311 | /** |
||
| 312 | * Checks if the time difference is less than 44mins 29seconds |
||
| 313 | * @param int $timeDifference the time difference in seconds |
||
| 314 | * @return bool |
||
| 315 | */ |
||
| 316 | private function isLessThan44Min29Secs($timeDifference) |
||
| 317 | { |
||
| 318 | return $timeDifference >= 90 && |
||
| 319 | $timeDifference <= (($this->secondsPerMinute * 44) + 29); |
||
| 320 | } |
||
| 321 | |||
| 322 | /** |
||
| 323 | * Checks if the time difference is less than 1hour 29mins 59seconds |
||
| 324 | * @param int $timeDifference the time difference in seconds |
||
| 325 | * @return bool |
||
| 326 | */ |
||
| 327 | private function isLessThan1Hour29Mins59Seconds($timeDifference) |
||
| 328 | { |
||
| 329 | return $timeDifference >= (($this->secondsPerMinute * 44) + 30) |
||
| 330 | && |
||
| 331 | $timeDifference <= ($this->secondsPerHour + ($this->secondsPerMinute * 29) + 59); |
||
| 332 | } |
||
| 333 | |||
| 334 | /** |
||
| 335 | * Checks if the time difference is less than 23hours 59mins 29seconds |
||
| 336 | * @param int $timeDifference the time difference in seconds |
||
| 337 | * @return bool |
||
| 338 | */ |
||
| 339 | private function isLessThan23Hours59Mins29Seconds($timeDifference) |
||
| 340 | { |
||
| 341 | return $timeDifference >= ( |
||
| 342 | $this->secondsPerHour + |
||
| 343 | ($this->secondsPerMinute * 30) |
||
| 344 | ) |
||
| 345 | && |
||
| 346 | $timeDifference <= ( |
||
| 347 | ($this->secondsPerHour * 23) + |
||
| 348 | ($this->secondsPerMinute * 59) + |
||
| 349 | 29 |
||
| 350 | ); |
||
| 351 | } |
||
| 352 | |||
| 353 | /** |
||
| 354 | * Checks if the time difference is less than 27hours 59mins 29seconds |
||
| 355 | * @param int $timeDifference the time difference in seconds |
||
| 356 | * @return bool |
||
| 357 | */ |
||
| 358 | private function isLessThan47Hours59Mins29Seconds($timeDifference) |
||
| 359 | { |
||
| 360 | return $timeDifference >= ( |
||
| 361 | ($this->secondsPerHour * 23) + |
||
| 362 | ($this->secondsPerMinute * 59) + |
||
| 363 | 30 |
||
| 364 | ) |
||
| 365 | && |
||
| 366 | $timeDifference <= ( |
||
| 367 | ($this->secondsPerHour * 47) + |
||
| 368 | ($this->secondsPerMinute * 59) + |
||
| 369 | 29 |
||
| 370 | ); |
||
| 371 | } |
||
| 372 | |||
| 373 | /** |
||
| 374 | * Checks if the time difference is less than 29days 23hours 59mins 29seconds |
||
| 375 | * @param int $timeDifference the time difference in seconds |
||
| 376 | * @return bool |
||
| 377 | */ |
||
| 378 | private function isLessThan29Days23Hours59Mins29Seconds($timeDifference) |
||
| 379 | { |
||
| 380 | return $timeDifference >= ( |
||
| 381 | ($this->secondsPerHour * 47) + |
||
| 382 | ($this->secondsPerMinute * 59) + |
||
| 383 | 30 |
||
| 384 | ) |
||
| 385 | && |
||
| 386 | $timeDifference <= ( |
||
| 387 | ($this->secondsPerDay * 29) + |
||
| 388 | ($this->secondsPerHour * 23) + |
||
| 389 | ($this->secondsPerMinute * 59) + |
||
| 390 | 29 |
||
| 391 | ); |
||
| 392 | } |
||
| 393 | |||
| 394 | /** |
||
| 395 | * Checks if the time difference is less than 59days 23hours 59mins 29seconds |
||
| 396 | * @param int $timeDifference the time difference in seconds |
||
| 397 | * @return bool |
||
| 398 | */ |
||
| 399 | private function isLessThan59Days23Hours59Mins29Secs($timeDifference) |
||
| 400 | { |
||
| 401 | return $timeDifference >= ( |
||
| 402 | ($this->secondsPerDay * 29) + |
||
| 403 | ($this->secondsPerHour * 23) + |
||
| 404 | ($this->secondsPerMinute * 59) + |
||
| 405 | 30 |
||
| 406 | ) |
||
| 407 | && |
||
| 408 | $timeDifference <= ( |
||
| 409 | ($this->secondsPerDay * 59) + |
||
| 410 | ($this->secondsPerHour * 23) + |
||
| 411 | ($this->secondsPerMinute * 59) + |
||
| 412 | 29 |
||
| 413 | ); |
||
| 414 | } |
||
| 415 | |||
| 416 | /** |
||
| 417 | * Checks if the time difference is less than 1 year |
||
| 418 | * @param int $timeDifference the time difference in seconds |
||
| 419 | * @return bool |
||
| 420 | */ |
||
| 421 | private function isLessThan1Year($timeDifference) |
||
| 422 | { |
||
| 423 | return $timeDifference >= ( |
||
| 424 | ($this->secondsPerDay * 59) + |
||
| 425 | ($this->secondsPerHour * 23) + |
||
| 426 | ($this->secondsPerMinute * 59) + |
||
| 427 | 30 |
||
| 428 | ) |
||
| 429 | && |
||
| 430 | $timeDifference < $this->secondsPerYear; |
||
| 431 | } |
||
| 432 | |||
| 433 | /** |
||
| 434 | * Checks if the time difference is less than 2 years |
||
| 435 | * @param int $timeDifference the time difference in seconds |
||
| 436 | * @return bool |
||
| 437 | */ |
||
| 438 | private function isLessThan2Years($timeDifference) |
||
| 439 | { |
||
| 440 | return $timeDifference >= $this->secondsPerYear |
||
| 441 | && |
||
| 442 | $timeDifference < ($this->secondsPerYear * 2); |
||
| 443 | } |
||
| 444 | } |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.