Passed
Pull Request — master (#247)
by Christopher
05:44 queued 02:26
created

DateTime::now()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 1
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace POData\Providers\Metadata\Type;
6
7
/**
8
 * Class DateTime.
9
 */
10
class DateTime implements IType
11
{
12
    protected static $comboRegex =
13
        "/^datetime\'(\d{4})-(\d{2})-(\d{2})((\s|T)([0-1][0-9]|2[0-4]):([0-5][0-9])(:([0-5][0-9])([Z]|[\+|-]\d{2}:\d{2})?)?)?\'$/";
14
15
    protected static $timeProvider = null;
16
17
    /**
18
     * Gets the type code
19
     * Note: implementation of IType::getTypeCode.
20
     *
21
     * @return TypeCode
22
     */
23
    public function getTypeCode()
24
    {
25
        return TypeCode::DATETIME();
26
    }
27
28
    /**
29
     * Checks this type is compatible with another type
30
     * Note: implementation of IType::isCompatibleWith.
31
     *
32
     * @param IType $type Type to check compatibility
33
     *
34
     * @return bool
35
     */
36
    public function isCompatibleWith(IType $type)
37
    {
38
        return TypeCode::DATETIME() == $type->getTypeCode();
39
    }
40
41
    /**
42
     * Validate a value in Astoria uri is in a format for this type
43
     * Note: implementation of IType::validate.
44
     *
45
     * @param string $value The value to validate
46
     * @param string &$outValue The stripped form of $value that can
47
     *                          be used in PHP expressions
48
     *
49
     * @return bool
50
     */
51
    public function validate($value, &$outValue)
52
    {
53
        //1. The datetime value present in the $filter option should have 'datetime' prefix.
54
        //2. Month and day should be two digit
55
        if (!preg_match(
56
            self::$comboRegex,
57
            strval($value),
58
            $matches
59
        )) {
60
            return false;
61
        }
62
63
        //strip off prefix, and quotes from both ends
64
        $value = trim($value, 'datetime\'');
65
        $valLen = strlen($value) - 6;
66
        $offsetChek = $value[$valLen];
67
        if (18 < $valLen && ('-' == $offsetChek || '+' == $offsetChek)) {
68
            $value = substr($value, 0, $valLen);
69
        }
70
71
        //Validate the date using PHP DateTime class
72
        try {
73
            new \DateTime($value, new \DateTimeZone('UTC'));
74
        } catch (\Exception $e) {
75
            return false;
76
        }
77
78
        $outValue = "'" . $value . "'";
79
80
        return true;
81
    }
82
83
    /**
84
     * Gets full name of this type in EDM namespace
85
     * Note: implementation of IType::getFullTypeName.
86
     *
87
     * @return string
88
     */
89
    public function getFullTypeName()
90
    {
91
        return 'Edm.DateTime';
92
    }
93
94
    /**
95
     * Converts the given string value to datetime type.
96
     * Note: This function will not perform any conversion.
97
     *
98
     * @param string $stringValue Value to convert
99
     *
100
     * @return string
101
     */
102
    public function convert($stringValue)
103
    {
104
        return $stringValue;
105
    }
106
107
    /**
108
     * Convert the given value to a form that can be used in OData uri.
109
     * Note: The calling function should not pass null value, as this
110
     * function will not perform any check for nullability.
111
     *
112
     * @param mixed $value Value to convert
113
     *
114
     * @return string
115
     */
116
    public function convertToOData($value)
117
    {
118
        return 'datetime\'' . urlencode($value) . '\'';
119
    }
120
121
    /**
122
     * Gets year from datetime.
123
     *
124
     * @param string $dateTime datetime to get the year from
125
     *
126
     * @return string
127
     * @throws \Exception
128
     */
129
    public static function year($dateTime)
130
    {
131
        $date = new \DateTime($dateTime);
132
133
        return $date->format('Y');
134
    }
135
136
    /**
137
     * Gets month from datetime.
138
     *
139
     * @param string $dateTime datetime to get the month from
140
     *
141
     * @return string
142
     * @throws \Exception
143
     */
144
    public static function month($dateTime)
145
    {
146
        $date = new \DateTime($dateTime);
147
148
        return $date->format('m');
149
    }
150
151
    /**
152
     * Gets day from datetime.
153
     *
154
     * @param string $dateTime datetime to get the day from
155
     *
156
     * @return string
157
     * @throws \Exception
158
     */
159
    public static function day($dateTime)
160
    {
161
        $date = new \DateTime($dateTime);
162
163
        return $date->format('d');
164
    }
165
166
    /**
167
     * Gets hour from datetime.
168
     *
169
     * @param string $dateTime datetime to get the hour from
170
     *
171
     * @return string
172
     * @throws \Exception
173
     */
174
    public static function hour($dateTime)
175
    {
176
        $date = new \DateTime($dateTime);
177
178
        return $date->format('H');
179
    }
180
181
    /**
182
     * Gets minute from datetime.
183
     *
184
     * @param string $dateTime datetime to get the minute from
185
     *
186
     * @return string
187
     * @throws \Exception
188
     */
189
    public static function minute($dateTime)
190
    {
191
        $date = new \DateTime($dateTime);
192
193
        return $date->format('i');
194
    }
195
196
    /**
197
     * Gets second from datetime.
198
     *
199
     * @param string $dateTime datetime to get the second from
200
     *
201
     * @return string
202
     * @throws \Exception
203
     */
204
    public static function second($dateTime)
205
    {
206
        $date = new \DateTime($dateTime);
207
208
        return $date->format('s');
209
    }
210
211
    /**
212
     * gets a datetime object for now either internally or from a time provider
213
     *
214
     * @return \DateTime a date time object that represents "now"
215
     * @throws \Exception
216
     */
217
    public static function now(): \DateTime
218
    {
219
        return null === self::$timeProvider ? new \DateTime() : call_user_func(self::$timeProvider);
220
    }
221
222
    /**
223
     * Compare two dates. Note that this function will not perform any
224
     * validation on dates, one should use either validate or
225
     * validateWithoutPrefix to validate the date before calling this
226
     * function.
227
     *
228
     * @param string $dateTime1 First date
229
     * @param string $dateTime2 Second date
230
     *
231
     * @return int
232
     * @throws \Exception
233
     */
234
    public static function dateTimeCmp($dateTime1, $dateTime2)
235
    {
236
        $firstStamp = self::dateTimeCmpCheckInput($dateTime1, 'Invalid input - datetime1 must be DateTime or string');
237
        $secondStamp = self::dateTimeCmpCheckInput($dateTime2, 'Invalid input - datetime2 must be DateTime or string');
238
239
        if ($firstStamp == $secondStamp) {
240
            return 0;
241
        }
242
        return $firstStamp < $secondStamp ? -1 : 1;
243
    }
244
245
    /**
246
     * Gets full name of the type implementing this interface in EDM namespace
247
     * Note: implementation of IType::getFullTypeName.
248
     *
249
     * @return string
250
     */
251
    public function getName()
252
    {
253
        return $this->getFullTypeName();
254
    }
255
256
    /**
257
     * @param $dateTime
258
     * @param $msg
259
     * @return false|int
260
     * @throws \Exception
261
     */
262
    protected static function dateTimeCmpCheckInput($dateTime, $msg)
263
    {
264
        if (is_object($dateTime) && $dateTime instanceof \DateTime) {
265
            $firstStamp = $dateTime->getTimestamp();
266
            return $firstStamp;
267
        }
268
        if (is_string($dateTime)) {
269
            $firstStamp = strtotime($dateTime);
270
            return $firstStamp;
271
        }
272
        throw new \Exception($msg);
273
    }
274
275
    public static function setTimeProvider(?callable $timeProvider): void
276
    {
277
        self::$timeProvider = $timeProvider;
278
    }
279
}
280