Passed
Pull Request — master (#247)
by Christopher
04:33
created

DateTime::second()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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