Merge pull request #18794 from eileenmcnaughton/need_less
[civicrm-core.git] / CRM / Utils / Time.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
16 */
17
18/**
19 * Date time utilties
20 */
21class CRM_Utils_Time {
22
23 /**
ea9371f9
TO
24 * A function which determines the current time.
25 * Only used during testing (with mocked time).
26 *
27 * The normal value, NULL, indicates the use of real time.
28 *
29 * @var callable|null
6a488035 30 */
ea9371f9 31 static private $callback = NULL;
6a488035
TO
32
33 /**
fe482240 34 * Get the time.
6a488035 35 *
77855840
TO
36 * @param string $returnFormat
37 * Format in which date is to be retrieved.
6a488035 38 *
2e9914a0 39 * @return string
6a488035 40 */
00be9182 41 public static function getTime($returnFormat = 'YmdHis') {
6a488035
TO
42 return date($returnFormat, self::getTimeRaw());
43 }
44
45 /**
fe482240 46 * Get the time.
6a488035 47 *
50bfb460
SB
48 * @return int
49 * seconds since epoch
6a488035 50 */
00be9182 51 public static function getTimeRaw() {
ea9371f9 52 return self::$callback === NULL ? time() : call_user_func(self::$callback);
6a488035
TO
53 }
54
55 /**
fe482240 56 * Set the given time.
6a488035 57 *
77855840
TO
58 * @param string $newDateTime
59 * A date formatted with strtotime.
60 * @param string $returnFormat
61 * Format in which date is to be retrieved.
6a488035 62 *
ea9371f9
TO
63 * Note: The progression of time will be influenced by TIME_FUNC, which may be:
64 * - 'frozen' (time does not move)
65 * - 'natural' (time moves naturally)
66 * - 'linear:XXX' (time moves in increments of XXX milliseconds - with every lookup)
67 * - 'prng:XXX' (time moves by random increments, between 0 and XXX milliseconds)
2e9914a0 68 * @return string
6a488035 69 */
00be9182 70 public static function setTime($newDateTime, $returnFormat = 'YmdHis') {
ea9371f9
TO
71 $mode = getenv('TIME_FUNC') ? getenv('TIME_FUNC') : 'natural';
72
73 list ($modeName, $modeNum) = explode(":", "$mode:");
74
75 switch ($modeName) {
76 case 'frozen':
77 // Every getTime() will produce the same value (ie $newDateTime).
78 $now = strtotime($newDateTime);
79 self::$callback = function () use ($now) {
80 return $now;
81 };
82 break;
83
84 case 'natural':
85 // Time changes to $newDateTime and then proceeds naturally.
86 $delta = strtotime($newDateTime) - time();
87 self::$callback = function () use ($delta) {
88 return time() + $delta;
89 };
90 break;
91
92 case 'linear':
93 // Time changes to $newDateTime and then proceeds in fixed increments ($modeNum milliseconds).
94 $incr = ($modeNum / 1000.0);
95 $now = (float) strtotime($newDateTime) - $incr;
96 self::$callback = function () use (&$now, $incr) {
97 $now += $incr;
98 return floor($now);
99 };
100 break;
101
102 case 'prng':
103 // Time changes to $newDateTime and then proceeds using deterministic pseudorandom increments (of up to $modeNum milliseconds).
104 $seed = md5($newDateTime . chr(0) . $mode, TRUE);
105 $now = (float) strtotime($newDateTime);
106 self::$callback = function () use (&$seed, &$now, $modeNum) {
107 $mod = gmp_strval(gmp_mod(gmp_import($seed), "$modeNum"));
108 $seed = md5($seed . $now, TRUE);
109 $now = $now + ($mod / 1000.0);
110 return floor($now);
111 };
112 break;
113
114 default:
115 throw new \RuntimeException("Unrecognized TIME_FUNC ($mode)");
116 }
117
6a488035
TO
118 return self::getTime($returnFormat);
119 }
120
121 /**
fe482240 122 * Remove any time overrides.
6a488035 123 */
00be9182 124 public static function resetTime() {
ea9371f9 125 self::$callback = NULL;
6a488035 126 }
8010540a
TO
127
128 /**
129 * Approximate time-comparison. $a and $b are considered equal if they
130 * are within $threshold seconds of each other.
131 *
77855840
TO
132 * @param string $a
133 * Time which can be parsed by strtotime.
134 * @param string $b
135 * Time which can be parsed by strtotime.
136 * @param int $threshold
137 * Maximum allowed difference (in seconds).
8010540a
TO
138 * @return bool
139 */
00be9182 140 public static function isEqual($a, $b, $threshold = 0) {
8010540a
TO
141 $diff = strtotime($b) - strtotime($a);
142 return (abs($diff) <= $threshold);
143 }
96025800 144
6a488035 145}