This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | // +---------------------------------------------------------------------------+ |
||
4 | // | This file is part of the Agavi package. | |
||
5 | // | Copyright (c) 2005-2011 the Agavi Project. | |
||
6 | // | | |
||
7 | // | For the full copyright and license information, please view the LICENSE | |
||
8 | // | file that was distributed with this source code. You can also view the | |
||
9 | // | LICENSE file online at http://www.agavi.org/LICENSE.txt | |
||
10 | // | vi: set noexpandtab: | |
||
11 | // | Local Variables: | |
||
12 | // | indent-tabs-mode: t | |
||
13 | // | End: | |
||
14 | // +---------------------------------------------------------------------------+ |
||
15 | |||
16 | namespace Agavi\Date; |
||
17 | |||
18 | use Agavi\Translation\Locale; |
||
19 | use Agavi\Translation\TranslationManager; |
||
20 | use Agavi\Util\Toolkit; |
||
21 | |||
22 | /** |
||
23 | * Ported from ICU: |
||
24 | * icu/trunk/source/i18n/calendar.cpp r22016 |
||
25 | * icu/trunk/source/i18n/unicode/calendar.h r22265 |
||
26 | * |
||
27 | * @package agavi |
||
28 | * @subpackage date |
||
29 | * |
||
30 | * @author Dominik del Bondio <[email protected]> |
||
31 | * @author The ICU Project |
||
32 | * @copyright Authors |
||
33 | * @copyright The Agavi Project |
||
34 | * |
||
35 | * @since 0.11.0 |
||
36 | * |
||
37 | * @version $Id$ |
||
38 | */ |
||
39 | abstract class Calendar |
||
40 | { |
||
41 | const GREGORIAN = 'gregorian'; |
||
42 | |||
43 | /** |
||
44 | * @var TranslationManager The translation manager instance. |
||
45 | * @since 0.11.0 |
||
46 | */ |
||
47 | protected $translationManager; |
||
48 | |||
49 | /** |
||
50 | * Returns the translation manager. |
||
51 | * |
||
52 | * @return TranslationManager The translation manager. |
||
53 | * |
||
54 | * @author Dominik del Bondio <[email protected]> |
||
55 | * @since 0.11.0 |
||
56 | */ |
||
57 | public function getTranslationManager() |
||
58 | { |
||
59 | return $this->translationManager; |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * Initialize the variables to default values. |
||
64 | * |
||
65 | * @author Dominik del Bondio <[email protected]> |
||
66 | * @author The ICU Project |
||
67 | * @since 0.11.0 |
||
68 | */ |
||
69 | protected function initVariables() |
||
70 | { |
||
71 | $this->fIsTimeSet = false; |
||
72 | $this->fAreFieldsInSync = false; |
||
73 | $this->fAreAllFieldsSet = false; |
||
74 | $this->fAreFieldsVirtuallySet = false; |
||
75 | $this->fNextStamp = self::kMinimumUserStamp; |
||
76 | $this->fTime = 0; |
||
0 ignored issues
–
show
|
|||
77 | $this->fLenient = true; |
||
78 | $this->fZone = null; |
||
79 | } |
||
80 | |||
81 | /** |
||
82 | * Called by the overload handler in the constructor. |
||
83 | * |
||
84 | * @param TimeZone $zone The timezone to use. |
||
85 | * @param Locale $locale The locale to use. |
||
86 | * |
||
87 | * @author Dominik del Bondio <[email protected]> |
||
88 | * @author The ICU Project |
||
89 | * @since 0.11.0 |
||
90 | */ |
||
91 | protected function constructorOO(TimeZone $zone, Locale $locale) |
||
92 | { |
||
93 | $this->translationManager = $zone->getTranslationManager(); |
||
94 | $this->clear(); |
||
95 | $this->fZone = clone $zone; |
||
96 | $this->setWeekCountData($locale, null); |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * Marker for end of resolve set (row or group). |
||
101 | */ |
||
102 | const RESOLVE_STOP = -1; |
||
103 | |||
104 | /** |
||
105 | * Value to be bitwised "ORed" against resolve table field values for |
||
106 | * remapping. Example: (UCAL_DATE | kResolveRemap) in 1st column will cause |
||
107 | * 'UCAL_DATE' to be returned, but will not examine the value of UCAL_DATE. |
||
108 | */ |
||
109 | const RESOLVE_REMAP = 32; |
||
110 | |||
111 | /** |
||
112 | * The minimum supported Julian day. This value is equivalent to |
||
113 | * MIN_MILLIS. |
||
114 | */ |
||
115 | const MIN_JULIAN = -19009842; // -0x7F000000; this was recalculated based on MIN_MILLIS |
||
116 | |||
117 | /** |
||
118 | * The minimum supported epoch milliseconds. This value is equivalent |
||
119 | * to MIN_JULIAN. |
||
120 | */ |
||
121 | const MIN_MILLIS = -1853317152000000.0; // ((MIN_JULIAN - kEpochStartAsJulianDay) * kOneDay) |
||
122 | |||
123 | /** |
||
124 | * The maximum supported Julian day. This value is equivalent to |
||
125 | * MAX_MILLIS. |
||
126 | */ |
||
127 | const MAX_JULIAN = 23939830.0; // (+0x7F000000) |
||
128 | |||
129 | /** |
||
130 | * The maximum supported epoch milliseconds. This value is equivalent |
||
131 | * to MAX_JULIAN. |
||
132 | */ |
||
133 | const MAX_MILLIS = 1857534508800000.0; // ((MAX_JULIAN - kEpochStartAsJulianDay) * kOneDay) |
||
134 | |||
135 | const LIMIT_MINIMUM = 0; |
||
136 | const LIMIT_GREATEST_MINIMUM = 1; |
||
137 | const LIMIT_LEAST_MAXIMUM = 2; |
||
138 | const LIMIT_MAXIMUM = 3; |
||
139 | const LIMIT_COUNT = 4; |
||
140 | |||
141 | protected static $kCalendarLimits = array( |
||
142 | // Minimum Greatest min Least max Greatest max |
||
143 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // ERA |
||
144 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // YEAR |
||
145 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // MONTH |
||
146 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // WEEK_OF_YEAR |
||
147 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // WEEK_OF_MONTH |
||
148 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // DAY_OF_MONTH |
||
149 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // DAY_OF_YEAR |
||
150 | array( 1, 1, 7, 7 ), // DAY_OF_WEEK |
||
151 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // DAY_OF_WEEK_IN_MONTH |
||
152 | array( 0, 0, 1, 1 ), // AM_PM |
||
153 | array( 0, 0, 11, 11 ), // HOUR |
||
154 | array( 0, 0, 23, 23 ), // HOUR_OF_DAY |
||
155 | array( 0, 0, 59, 59 ), // MINUTE |
||
156 | array( 0, 0, 59, 59 ), // SECOND |
||
157 | array( 0, 0, 999, 999 ), // MILLISECOND |
||
158 | // -12*self::kOneHour, -12*self::kOneHour, 12*self::kOneHour, 15*self::kOneHour |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
52% 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. ![]() |
|||
159 | array( -43200000, -43200000, 43200000, 54000000 ), // ZONE_OFFSET |
||
160 | array( 0, 0,DateDefinitions::MILLIS_PER_HOUR , DateDefinitions::MILLIS_PER_HOUR ), // DST_OFFSET |
||
161 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // YEAR_WOY |
||
162 | array( 1, 1, 7, 7 ), // DOW_LOCAL |
||
163 | array( /*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1 ), // EXTENDED_YEAR |
||
164 | array( self::MIN_JULIAN, self::MIN_JULIAN, self::MAX_JULIAN, self::MAX_JULIAN ), // JULIAN_DAY |
||
165 | // 0, 0, 24*self::kOneHour-1, 24*self::kOneHour-1 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
57% 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. ![]() |
|||
166 | array( 0, 0, 86399999, 86399999 ), // MILLISECONDS_IN_DAY |
||
167 | ); |
||
168 | |||
169 | /** |
||
170 | * Returns the current UTC (GMT) time measured in milliseconds since 0:00:00 |
||
171 | * on 1/1/70 (derived from the system time). |
||
172 | * |
||
173 | * @return float The current UTC time in milliseconds. |
||
174 | * |
||
175 | * @author Dominik del Bondio <[email protected]> |
||
176 | * @author The ICU Project |
||
177 | * @since 0.11.0 |
||
178 | */ |
||
179 | public static function getNow() |
||
180 | { |
||
181 | return time() * DateDefinitions::MILLIS_PER_SECOND; |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * Gets this Calendar's time as milliseconds. May involve recalculation of |
||
186 | * time due to previous calls to set time field values. The time specified is |
||
187 | * non-local UTC (GMT) time. |
||
188 | * |
||
189 | * @return float The current time in UTC (GMT) time, or zero if the |
||
190 | * operation failed. |
||
191 | * |
||
192 | * @author Dominik del Bondio <[email protected]> |
||
193 | * @author The ICU Project |
||
194 | * @since 0.11.0 |
||
195 | */ |
||
196 | public function getTime() |
||
197 | { |
||
198 | return $this->getTimeInMillis(); |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Sets this Calendar's current time with the given UDate. The time specified |
||
203 | * should be in non-local UTC (GMT) time. |
||
204 | * |
||
205 | * @param float The given UDate in UTC (GMT) time. |
||
206 | * |
||
207 | * @author Dominik del Bondio <[email protected]> |
||
208 | * @author The ICU Project |
||
209 | * @since 0.11.0 |
||
210 | */ |
||
211 | public function setTime($date) |
||
212 | { |
||
213 | $this->setTimeInMillis($date); |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Returns the php native DateTime object which represents the time of this |
||
218 | * object. Also supports dates which are not in the range of a unix timestamp. |
||
219 | * It will also set the DateTime object to be in the same time zone as this |
||
220 | * Calendar object. |
||
221 | * Please note that this method will only work on PHP 5.1.x when you have |
||
222 | * explicitly enabled the new DateTime support. This restriction does not |
||
223 | * apply to 5.2 and upwards. |
||
224 | * When the Calendar object is in the AD era, the result of the conversion |
||
225 | * is undefined. |
||
226 | * |
||
227 | * @return \DateTime The native DateTime. |
||
228 | * |
||
229 | * @author Dominik del Bondio <[email protected]> |
||
230 | * @since 0.11.0 |
||
231 | */ |
||
232 | public function getNativeDateTime() |
||
233 | { |
||
234 | $dateTimeString = sprintf( |
||
235 | '%d-%d-%d %d:%d:%d', |
||
236 | $this->get(DateDefinitions::YEAR), $this->get(DateDefinitions::MONTH) + 1, $this->get(DateDefinitions::DATE), |
||
237 | $this->get(DateDefinitions::HOUR_OF_DAY), $this->get(DateDefinitions::MINUTE), $this->get(DateDefinitions::SECOND) |
||
238 | ); |
||
239 | |||
240 | $tz = $this->getTimeZone(); |
||
241 | // check if this is a custom timezone (they have GMT+0000 as id and could potentially contain seconds as well, so we allow up to 6 digits) |
||
242 | if (preg_match('#GMT[+-]\d{4,6}#', $tz->getId())) { |
||
243 | return new \DateTime($dateTimeString . $tz->formatOffset(false, '', '')); |
||
244 | } else { |
||
245 | return new \DateTime($dateTimeString, new \DateTimeZone($tz->getId())); |
||
246 | } |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * Gets this Calendar's time as unix timestamp. May involve recalculation of |
||
251 | * time due to previous calls to set time field values. The time specified is |
||
252 | * non-local UTC (GMT) time. |
||
253 | * |
||
254 | * @return int The current time in UTC (GMT) time as unix timestamp. |
||
255 | * |
||
256 | * @throws <b>OverflowException</b> when the date can't be represented by |
||
257 | * an unix timestamp. |
||
258 | * |
||
259 | * @author Dominik del Bondio <[email protected]> |
||
260 | * @since 0.11.0 |
||
261 | */ |
||
262 | public function getUnixTimestamp() |
||
263 | { |
||
264 | $unixTime = floor($this->getTimeInMillis() / DateDefinitions::MILLIS_PER_SECOND); |
||
265 | $unixTimeInt = (int) $unixTime; |
||
266 | // lets check if the int can't represent the time anymore |
||
267 | if ($unixTime != $unixTimeInt) { |
||
268 | throw new \OverflowException('cannot convert the date ' . $this->get(DateDefinitions::YEAR) . '/' . $this->get(DateDefinitions::MONTH) . '/' . $this->get(DateDefinitions::DATE) . ' into a unix timestamp'); |
||
269 | } |
||
270 | return $unixTimeInt; |
||
271 | } |
||
272 | |||
273 | /** |
||
274 | * Sets this Calendar's current time with the given unix timestamp. The time |
||
275 | * specified should be in non-local UTC (GMT) time. |
||
276 | * |
||
277 | * @param int $timestamp The given date in UTC (GMT) time. |
||
278 | * |
||
279 | * @author Dominik del Bondio <[email protected]> |
||
280 | * @since 0.11.0 |
||
281 | */ |
||
282 | public function setUnixTimestamp($timestamp) |
||
283 | { |
||
284 | $this->setTimeInMillis($timestamp * DateDefinitions::MILLIS_PER_SECOND); |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * @see Calendar::getAll() |
||
289 | * |
||
290 | * @author Dominik del Bondio <[email protected]> |
||
291 | * @since 1.0.0 |
||
292 | */ |
||
293 | public function toArray() |
||
294 | { |
||
295 | return $this->getAll(); |
||
296 | } |
||
297 | |||
298 | /** |
||
299 | * Sets all given time field values. |
||
300 | * |
||
301 | * @param array $data An array using the DateDefinitions::XXX as key |
||
302 | * and the respective value as value. |
||
303 | * |
||
304 | * @author Dominik del Bondio <[email protected]> |
||
305 | * @since 1.0.0 |
||
306 | */ |
||
307 | public function fromArray(array $data) |
||
308 | { |
||
309 | foreach ($data as $key => $value) { |
||
310 | $this->set1($key, $value); |
||
311 | } |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * Returns the locale option string containing the timezone option set |
||
316 | * to the timezone of this calendar. |
||
317 | * |
||
318 | * @param string $prefix The prefix which will be applied to the timezone option |
||
319 | * string. Use ';' here if you intend to use several |
||
320 | * locale options and append the result of this method |
||
321 | * to your locale string. |
||
322 | * |
||
323 | * @return string |
||
324 | * |
||
325 | * @author Dominik del Bondio <[email protected]> |
||
326 | * @since 1.0.0 |
||
327 | */ |
||
328 | public function getTimeZoneLocaleOptionString($prefix = '@') |
||
329 | { |
||
330 | return Locale::getTimeZoneOptionString($this, $prefix); |
||
331 | } |
||
332 | |||
333 | public function __is_equal(Calendar $that) |
||
334 | { |
||
335 | return $this->isEquivalentTo($that) && $this->getTimeInMillis() == $that->getTimeInMillis(); |
||
336 | } |
||
337 | |||
338 | public function __is_not_equal(Calendar $that) |
||
339 | { |
||
340 | return !$this->isEquivalentTo($that) || $this->getTimeInMillis() != $that->getTimeInMillis(); |
||
341 | } |
||
342 | |||
343 | /** |
||
344 | * Returns TRUE if the given Calendar object is equivalent to this |
||
345 | * one. An equivalent Calendar will behave exactly as this one |
||
346 | * does, but it may be set to a different time. By contrast, for |
||
347 | * the operator==() method to return TRUE, the other Calendar must |
||
348 | * be set to the same time. |
||
349 | * |
||
350 | * @param Calendar the Calendar to be compared with this Calendar |
||
351 | * |
||
352 | * @return bool |
||
353 | * |
||
354 | * @author Dominik del Bondio <[email protected]> |
||
355 | * @author The ICU Project |
||
356 | * @since 0.11.0 |
||
357 | */ |
||
358 | public function isEquivalentTo(Calendar $other) |
||
359 | { |
||
360 | return get_class($this) == get_class($other) && |
||
361 | $this->isLenient() == $other->isLenient() && |
||
362 | $this->getFirstDayOfWeek() == $other->getFirstDayOfWeek() && |
||
363 | $this->getMinimalDaysInFirstWeek() == $other->getMinimalDaysInFirstWeek() && |
||
364 | $this->getTimeZone()->__is_equal($other->getTimeZone()); |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * Compares the Calendar time, whereas Calendar::operator== compares the |
||
369 | * equality of Calendar objects. |
||
370 | * |
||
371 | * @param Calendar $when The Calendar to be compared with this Calendar. |
||
372 | * The object may be modified physically |
||
373 | * |
||
374 | * @return bool True if the current time of this Calendar is equal to the |
||
375 | * time of Calendar when; false otherwise. |
||
376 | * |
||
377 | * @author Dominik del Bondio <[email protected]> |
||
378 | * @author The ICU Project |
||
379 | * @since 0.11.0 |
||
380 | */ |
||
381 | public function equals(Calendar $when) |
||
382 | { |
||
383 | return ($this->__is_equal($when) || $this->getTime() == $when->getTime()); |
||
384 | } |
||
385 | |||
386 | /** |
||
387 | * Returns true if this Calendar's current time is before "when"'s current |
||
388 | * time. |
||
389 | * |
||
390 | * @param Calendar $when The Calendar to be compared with this Calendar. |
||
391 | * The object may be modified physically. |
||
392 | * |
||
393 | * @return bool True if the current time of this Calendar is before the |
||
394 | * time of Calendar when; false otherwise. |
||
395 | * |
||
396 | * @author Dominik del Bondio <[email protected]> |
||
397 | * @author The ICU Project |
||
398 | * @since 0.11.0 |
||
399 | */ |
||
400 | public function before(Calendar $when) |
||
401 | { |
||
402 | return ($this->__is_not_equal($when) && $this->getTimeInMillis() < $when->getTimeInMillis()); |
||
403 | } |
||
404 | |||
405 | /** |
||
406 | * Returns true if this Calendar's current time is after "when"'s current |
||
407 | * time. |
||
408 | * |
||
409 | * @param Calendar $when The Calendar to be compared with this Calendar. |
||
410 | * The object may be modified physically. |
||
411 | * |
||
412 | * @return bool True if the current time of this Calendar is after the |
||
413 | * time of Calendar when; false otherwise. |
||
414 | * |
||
415 | * @author Dominik del Bondio <[email protected]> |
||
416 | * @author The ICU Project |
||
417 | * @since 0.11.0 |
||
418 | */ |
||
419 | public function after(Calendar $when) |
||
420 | { |
||
421 | return ($this->__is_not_equal($when) && $this->getTimeInMillis() > $when->getTimeInMillis()); |
||
422 | } |
||
423 | |||
424 | /** |
||
425 | * UDate Arithmetic function. Adds the specified (signed) amount of time to |
||
426 | * the given time field, based on the calendar's rules. For example, to |
||
427 | * subtract 5 days from the current time of the calendar, call |
||
428 | * add(DateDefinitions::DATE, -5). When adding on the month or |
||
429 | * DateDefinitions::DATE field, other fields like date might conflict |
||
430 | * and need to be changed. For instance, adding 1 month on the date 01/31/96 |
||
431 | * will result in 02/29/96. |
||
432 | * |
||
433 | * @param int $field Specifies which date field to modify. |
||
434 | * @param int $amount The amount of time to be added to the field, in the natural |
||
435 | * unit for that field (e.g., days for the day fields, hours |
||
436 | * for the hour field.) |
||
437 | * |
||
438 | * @author Dominik del Bondio <[email protected]> |
||
439 | * @author The ICU Project |
||
440 | * @since 0.11.0 |
||
441 | */ |
||
442 | public function add($field, $amount) |
||
443 | { |
||
444 | if ($amount == 0) { |
||
445 | return; // Do nothing! |
||
446 | } |
||
447 | |||
448 | // We handle most fields in the same way. The algorithm is to add |
||
449 | // a computed amount of millis to the current millis. The only |
||
450 | // wrinkle is with DST -- for some fields, like the DAY_OF_MONTH, |
||
451 | // we don't want the HOUR to shift due to changes in DST. If the |
||
452 | // result of the add operation is to move from DST to Standard, or |
||
453 | // vice versa, we need to adjust by an hour forward or back, |
||
454 | // respectively. For such fields we set keepHourInvariant to TRUE. |
||
455 | |||
456 | // We only adjust the DST for fields larger than an hour. For |
||
457 | // fields smaller than an hour, we cannot adjust for DST without |
||
458 | // causing problems. for instance, if you add one hour to April 5, |
||
459 | // 1998, 1:00 AM, in PST, the time becomes "2:00 AM PDT" (an |
||
460 | // illegal value), but then the adjustment sees the change and |
||
461 | // compensates by subtracting an hour. As a result the time |
||
462 | // doesn't advance at all. |
||
463 | |||
464 | // For some fields larger than a day, such as a UCAL_MONTH, we pin the |
||
465 | // UCAL_DAY_OF_MONTH. This allows <March 31>.add(UCAL_MONTH, 1) to be |
||
466 | // <April 30>, rather than <April 31> => <May 1>. |
||
467 | |||
468 | $delta = (float) $amount; // delta in ms |
||
469 | $keepHourInvariant = true; |
||
470 | |||
471 | switch ($field) { |
||
472 | View Code Duplication | case DateDefinitions::ERA: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
473 | $this->set($field, $this->get($field) + $amount); |
||
474 | $this->pinField(DateDefinitions::ERA); |
||
475 | return; |
||
476 | |||
477 | case DateDefinitions::YEAR: |
||
478 | case DateDefinitions::EXTENDED_YEAR: |
||
479 | case DateDefinitions::YEAR_WOY: |
||
480 | View Code Duplication | case DateDefinitions::MONTH: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
481 | $this->set($field, $this->get($field) + $amount); |
||
482 | $this->pinField(DateDefinitions::DAY_OF_MONTH); |
||
483 | return; |
||
484 | |||
485 | case DateDefinitions::WEEK_OF_YEAR: |
||
486 | case DateDefinitions::WEEK_OF_MONTH: |
||
487 | case DateDefinitions::DAY_OF_WEEK_IN_MONTH: |
||
488 | $delta *= DateDefinitions::MILLIS_PER_WEEK; |
||
489 | break; |
||
490 | |||
491 | case DateDefinitions::AM_PM: |
||
492 | $delta *= 12 * DateDefinitions::MILLIS_PER_HOUR; |
||
493 | break; |
||
494 | |||
495 | case DateDefinitions::DAY_OF_MONTH: |
||
496 | case DateDefinitions::DAY_OF_YEAR: |
||
497 | case DateDefinitions::DAY_OF_WEEK: |
||
498 | case DateDefinitions::DOW_LOCAL: |
||
499 | case DateDefinitions::JULIAN_DAY: |
||
500 | $delta *= DateDefinitions::MILLIS_PER_DAY; |
||
501 | break; |
||
502 | |||
503 | case DateDefinitions::HOUR_OF_DAY: |
||
504 | case DateDefinitions::HOUR: |
||
505 | $delta *= DateDefinitions::MILLIS_PER_HOUR; |
||
506 | $keepHourInvariant = false; |
||
507 | break; |
||
508 | |||
509 | case DateDefinitions::MINUTE: |
||
510 | $delta *= DateDefinitions::MILLIS_PER_MINUTE; |
||
511 | $keepHourInvariant = false; |
||
512 | break; |
||
513 | |||
514 | case DateDefinitions::SECOND: |
||
515 | $delta *= DateDefinitions::MILLIS_PER_SECOND; |
||
516 | $keepHourInvariant = false; |
||
517 | break; |
||
518 | |||
519 | case DateDefinitions::MILLISECOND: |
||
520 | case DateDefinitions::MILLISECONDS_IN_DAY: |
||
521 | $keepHourInvariant = false; |
||
522 | break; |
||
523 | |||
524 | default: |
||
525 | throw new \InvalidArgumentException('Calendar::add(): field ' . $field . ' is not supported'); |
||
526 | } |
||
527 | |||
528 | // In order to keep the hour invariant (for fields where this is |
||
529 | // appropriate), record the DST_OFFSET before and after the add() |
||
530 | // operation. If it has changed, then adjust the millis to |
||
531 | // compensate. |
||
532 | $dst = 0; |
||
533 | $hour = 0; |
||
534 | if ($keepHourInvariant) { |
||
535 | $dst = $this->get(DateDefinitions::DST_OFFSET); |
||
536 | $hour = $this->internalGet(DateDefinitions::HOUR_OF_DAY); |
||
537 | } |
||
538 | |||
539 | $this->setTimeInMillis($this->getTimeInMillis() + $delta); |
||
540 | |||
541 | if ($keepHourInvariant) { |
||
542 | $dst -= $this->get(DateDefinitions::DST_OFFSET); |
||
543 | if ($dst != 0) { |
||
544 | // We have done an hour-invariant adjustment but the |
||
545 | // DST offset has altered. We adjust millis to keep |
||
546 | // the hour constant. In cases such as midnight after |
||
547 | // a DST change which occurs at midnight, there is the |
||
548 | // danger of adjusting into a different day. To avoid |
||
549 | // this we make the adjustment only if it actually |
||
550 | // maintains the hour. |
||
551 | |||
552 | /* double */ |
||
553 | $t = $this->internalGetTime(); |
||
554 | $this->setTimeInMillis($t + $dst); |
||
555 | if ($this->get(DateDefinitions::HOUR_OF_DAY) != $hour) { |
||
556 | $this->setTimeInMillis($t); |
||
557 | } |
||
558 | } |
||
559 | } |
||
560 | } |
||
561 | |||
562 | /** |
||
563 | * Time Field Rolling function. Rolls by the given amount on the given |
||
564 | * time field. For example, to roll the current date up by one day, call |
||
565 | * roll(DateDefinitions::DATE, +1). When rolling on the month or |
||
566 | * DateDefinitions::MONTH field, other fields like date might |
||
567 | * conflict and, need to be changed. For instance, rolling the month up on the |
||
568 | * date 01/31/96 will result in 02/29/96. Rolling by a positive value always |
||
569 | * means rolling forward in time; e.g., rolling the year by +1 on "100 BC" |
||
570 | * will result in "99 BC", for Gregorian calendar. When rolling on the |
||
571 | * hour-in-day or DateDefinitions::HOUR_OF_DAY field, it will |
||
572 | * roll the hour value in the range between 0 and 23, which is zero-based. |
||
573 | * <P> |
||
574 | * The only difference between roll() and add() is that roll() does not change |
||
575 | * the value of more significant fields when it reaches the minimum or maximum |
||
576 | * of its range, whereas add() does. |
||
577 | * |
||
578 | * @param int $field The time field. |
||
579 | * @param int $amount Indicates amount to roll. |
||
580 | * |
||
581 | * @author Dominik del Bondio <[email protected]> |
||
582 | * @author The ICU Project |
||
583 | * @since 0.11.0 |
||
584 | */ |
||
585 | public function roll($field, $amount) |
||
586 | { |
||
587 | // this is overloaded in c++ with roll($field, $up) |
||
588 | if (is_bool($amount)) { |
||
589 | $amount = $amount ? +1 : -1; |
||
590 | } |
||
591 | |||
592 | if ($amount == 0) { |
||
593 | return; // Nothing to do |
||
594 | } |
||
595 | |||
596 | $this->complete(); |
||
597 | |||
598 | switch ($field) { |
||
599 | case DateDefinitions::DAY_OF_MONTH: |
||
600 | case DateDefinitions::AM_PM: |
||
601 | case DateDefinitions::MINUTE: |
||
602 | case DateDefinitions::SECOND: |
||
603 | case DateDefinitions::MILLISECOND: |
||
604 | case DateDefinitions::MILLISECONDS_IN_DAY: |
||
605 | case DateDefinitions::ERA: |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
606 | // These are the standard roll instructions. These work for all |
||
607 | // simple cases, that is, cases in which the limits are fixed, such |
||
608 | // as the hour, the day of the month, and the era. |
||
609 | { |
||
610 | $min = $this->getActualMinimum($field); |
||
611 | $max = $this->getActualMaximum($field); |
||
612 | $gap = $max - $min + 1; |
||
613 | |||
614 | $value = $this->internalGet($field) + $amount; |
||
615 | $value = ($value - $min) % $gap; |
||
616 | if ($value < 0) { |
||
617 | $value += $gap; |
||
618 | } |
||
619 | $value += $min; |
||
620 | |||
621 | $this->set($field, $value); |
||
622 | return; |
||
623 | } |
||
624 | |||
625 | case DateDefinitions::HOUR: |
||
626 | case DateDefinitions::HOUR_OF_DAY: |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
627 | // Rolling the hour is difficult on the ONSET and CEASE days of |
||
628 | // daylight savings. For example, if the change occurs at |
||
629 | // 2 AM, we have the following progression: |
||
630 | // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst |
||
631 | // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std |
||
632 | // To get around this problem we don't use fields; we manipulate |
||
633 | // the time in millis directly. |
||
634 | { |
||
635 | // Assume min == 0 in calculations below |
||
636 | /* double */ $start = $this->getTimeInMillis(); |
||
637 | $oldHour = $this->internalGet($field); |
||
638 | $max = $this->getMaximum($field); |
||
639 | $newHour = ($oldHour + $amount) % ($max + 1); |
||
640 | if ($newHour < 0) { |
||
641 | $newHour += $max + 1; |
||
642 | } |
||
643 | $this->setTimeInMillis($start + DateDefinitions::MILLIS_PER_HOUR * ($newHour - $oldHour)); |
||
644 | return; |
||
645 | } |
||
646 | |||
647 | case DateDefinitions::MONTH: |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
648 | // Rolling the month involves both pinning the final value |
||
649 | // and adjusting the DAY_OF_MONTH if necessary. We only adjust the |
||
650 | // DAY_OF_MONTH if, after updating the MONTH field, it is illegal. |
||
651 | // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>. |
||
652 | { |
||
653 | $max = $this->getActualMaximum(DateDefinitions::MONTH); |
||
654 | $mon = ($this->internalGet(DateDefinitions::MONTH) + $amount) % ($max + 1); |
||
655 | |||
656 | if ($mon < 0) { |
||
657 | $mon += ($max + 1); |
||
658 | } |
||
659 | $this->set(DateDefinitions::MONTH, $mon); |
||
660 | |||
661 | // Keep the day of month in range. We don't want to spill over |
||
662 | // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 -> |
||
663 | // mar3. |
||
664 | $this->pinField(DateDefinitions::DAY_OF_MONTH); |
||
665 | return; |
||
666 | } |
||
667 | |||
668 | case DateDefinitions::YEAR: |
||
669 | case DateDefinitions::YEAR_WOY: |
||
670 | View Code Duplication | case DateDefinitions::EXTENDED_YEAR: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
671 | // Rolling the year can involve pinning the DAY_OF_MONTH. |
||
672 | $this->set($field, $this->internalGet($field) + $amount); |
||
673 | $this->pinField(DateDefinitions::MONTH); |
||
674 | $this->pinField(DateDefinitions::DAY_OF_MONTH); |
||
675 | return; |
||
676 | |||
677 | View Code Duplication | case DateDefinitions::WEEK_OF_MONTH: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
678 | { |
||
679 | // This is tricky, because during the roll we may have to shift |
||
680 | // to a different day of the week. For example: |
||
681 | |||
682 | // s m t w r f s |
||
683 | // 1 2 3 4 5 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% 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. ![]() |
|||
684 | // 6 7 8 9 10 11 12 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% 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. ![]() |
|||
685 | |||
686 | // When rolling from the 6th or 7th back one week, we go to the |
||
687 | // 1st (assuming that the first partial week counts). The same |
||
688 | // thing happens at the end of the month. |
||
689 | |||
690 | // The other tricky thing is that we have to figure out whether |
||
691 | // the first partial week actually counts or not, based on the |
||
692 | // minimal first days in the week. And we have to use the |
||
693 | // correct first day of the week to delineate the week |
||
694 | // boundaries. |
||
695 | |||
696 | // Here's our algorithm. First, we find the real boundaries of |
||
697 | // the month. Then we discard the first partial week if it |
||
698 | // doesn't count in this locale. Then we fill in the ends with |
||
699 | // phantom days, so that the first partial week and the last |
||
700 | // partial week are full weeks. We then have a nice square |
||
701 | // block of weeks. We do the usual rolling within this block, |
||
702 | // as is done elsewhere in this method. If we wind up on one of |
||
703 | // the phantom days that we added, we recognize this and pin to |
||
704 | // the first or the last day of the month. Easy, eh? |
||
705 | |||
706 | // Normalize the DAY_OF_WEEK so that 0 is the first day of the week |
||
707 | // in this locale. We have dow in 0..6. |
||
708 | $dow = $this->internalGet(DateDefinitions::DAY_OF_WEEK) - $this->getFirstDayOfWeek(); |
||
709 | if ($dow < 0) { |
||
710 | $dow += 7; |
||
711 | } |
||
712 | |||
713 | // Find the day of the week (normalized for locale) for the first |
||
714 | // of the month. |
||
715 | $fdm = ($dow - $this->internalGet(DateDefinitions::DAY_OF_MONTH) + 1) % 7; |
||
716 | if ($fdm < 0) { |
||
717 | $fdm += 7; |
||
718 | } |
||
719 | |||
720 | // Get the first day of the first full week of the month, |
||
721 | // including phantom days, if any. Figure out if the first week |
||
722 | // counts or not; if it counts, then fill in phantom days. If |
||
723 | // not, advance to the first real full week (skip the partial week). |
||
724 | if ((7 - $fdm) < $this->getMinimalDaysInFirstWeek()) { |
||
725 | $start = 8 - $fdm; // Skip the first partial week |
||
726 | } else { |
||
727 | $start = 1 - $fdm; // This may be zero or negative |
||
728 | } |
||
729 | |||
730 | // Get the day of the week (normalized for locale) for the last |
||
731 | // day of the month. |
||
732 | $monthLen = $this->getActualMaximum(DateDefinitions::DAY_OF_MONTH); |
||
733 | $ldm = ($monthLen - $this->internalGet(DateDefinitions::DAY_OF_MONTH) + $dow) % 7; |
||
734 | // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here. |
||
735 | |||
736 | // Get the limit day for the blocked-off rectangular month; that |
||
737 | // is, the day which is one past the last day of the month, |
||
738 | // after the month has already been filled in with phantom days |
||
739 | // to fill out the last week. This day has a normalized DOW of 0. |
||
740 | $limit = $monthLen + 7 - $ldm; |
||
741 | |||
742 | // Now roll between start and (limit - 1). |
||
743 | $gap = $limit - $start; |
||
744 | $day_of_month = ($this->internalGet(DateDefinitions::DAY_OF_MONTH) + $amount * 7 - $start) % $gap; |
||
745 | if ($day_of_month < 0) { |
||
746 | $day_of_month += $gap; |
||
747 | } |
||
748 | $day_of_month += $start; |
||
749 | |||
750 | // Finally, pin to the real start and end of the month. |
||
751 | if ($day_of_month < 1) { |
||
752 | $day_of_month = 1; |
||
753 | } |
||
754 | if ($day_of_month > $monthLen) { |
||
755 | $day_of_month = $monthLen; |
||
756 | } |
||
757 | |||
758 | // Set the DAY_OF_MONTH. We rely on the fact that this field |
||
759 | // takes precedence over everything else (since all other fields |
||
760 | // are also set at this point). If this fact changes (if the |
||
761 | // disambiguation algorithm changes) then we will have to unset |
||
762 | // the appropriate fields here so that DAY_OF_MONTH is attended |
||
763 | // to. |
||
764 | $this->set(DateDefinitions::DAY_OF_MONTH, $day_of_month); |
||
765 | return; |
||
766 | } |
||
767 | View Code Duplication | case DateDefinitions::WEEK_OF_YEAR: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
768 | { |
||
769 | // This follows the outline of WEEK_OF_MONTH, except it applies |
||
770 | // to the whole year. Please see the comment for WEEK_OF_MONTH |
||
771 | // for general notes. |
||
772 | |||
773 | // Normalize the DAY_OF_WEEK so that 0 is the first day of the week |
||
774 | // in this locale. We have dow in 0..6. |
||
775 | $dow = $this->internalGet(DateDefinitions::DAY_OF_WEEK) - $this->getFirstDayOfWeek(); |
||
776 | if ($dow < 0) { |
||
777 | $dow += 7; |
||
778 | } |
||
779 | |||
780 | // Find the day of the week (normalized for locale) for the first |
||
781 | // of the year. |
||
782 | $fdy = ($dow - $this->internalGet(DateDefinitions::DAY_OF_YEAR) + 1) % 7; |
||
783 | if ($fdy < 0) { |
||
784 | $fdy += 7; |
||
785 | } |
||
786 | |||
787 | // Get the first day of the first full week of the year, |
||
788 | // including phantom days, if any. Figure out if the first week |
||
789 | // counts or not; if it counts, then fill in phantom days. If |
||
790 | // not, advance to the first real full week (skip the partial week). |
||
791 | if ((7 - $fdy) < $this->getMinimalDaysInFirstWeek()) { |
||
792 | $start = 8 - $fdy; // Skip the first partial week |
||
793 | } else { |
||
794 | $start = 1 - $fdy; // This may be zero or negative |
||
795 | } |
||
796 | |||
797 | // Get the day of the week (normalized for locale) for the last |
||
798 | // day of the year. |
||
799 | $yearLen = $this->getActualMaximum(DateDefinitions::DAY_OF_YEAR); |
||
800 | $ldy = ($yearLen - $this->internalGet(DateDefinitions::DAY_OF_YEAR) + $dow) % 7; |
||
801 | // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here. |
||
802 | |||
803 | // Get the limit day for the blocked-off rectangular year; that |
||
804 | // is, the day which is one past the last day of the year, |
||
805 | // after the year has already been filled in with phantom days |
||
806 | // to fill out the last week. This day has a normalized DOW of 0. |
||
807 | $limit = $yearLen + 7 - $ldy; |
||
808 | |||
809 | // Now roll between start and (limit - 1). |
||
810 | $gap = $limit - $start; |
||
811 | $day_of_year = ($this->internalGet(DateDefinitions::DAY_OF_YEAR) + $amount * 7 - $start) % $gap; |
||
812 | if ($day_of_year < 0) { |
||
813 | $day_of_year += $gap; |
||
814 | } |
||
815 | $day_of_year += $start; |
||
816 | |||
817 | // Finally, pin to the real start and end of the month. |
||
818 | if ($day_of_year < 1) { |
||
819 | $day_of_year = 1; |
||
820 | } |
||
821 | if ($day_of_year > $yearLen) { |
||
822 | $day_of_year = $yearLen; |
||
823 | } |
||
824 | |||
825 | // Make sure that the year and day of year are attended to by |
||
826 | // clearing other fields which would normally take precedence. |
||
827 | // If the disambiguation algorithm is changed, this section will |
||
828 | // have to be updated as well. |
||
829 | $this->set(DateDefinitions::DAY_OF_YEAR, $day_of_year); |
||
830 | $this->clear(DateDefinitions::MONTH); |
||
831 | return; |
||
832 | } |
||
833 | case DateDefinitions::DAY_OF_YEAR: |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
834 | { |
||
835 | // Roll the day of year using millis. Compute the millis for |
||
836 | // the start of the year, and get the length of the year. |
||
837 | $delta = (float) ($amount * DateDefinitions::MILLIS_PER_DAY); // Scale up from days to millis |
||
838 | $min2 = (float) ($this->internalGet(DateDefinitions::DAY_OF_YEAR) - 1); |
||
839 | $min2 *= DateDefinitions::MILLIS_PER_DAY; |
||
840 | $min2 = $this->internalGetTime() - $min2; |
||
841 | |||
842 | $yearLength = (float) $this->getActualMaximum(DateDefinitions::DAY_OF_YEAR); |
||
843 | $oneYear = $yearLength; |
||
844 | $oneYear *= DateDefinitions::MILLIS_PER_DAY; |
||
845 | $newtime = fmod(($this->internalGetTime() + $delta - $min2), $oneYear); |
||
846 | if ($newtime < 0) { |
||
847 | $newtime += $oneYear; |
||
848 | } |
||
849 | $this->setTimeInMillis($newtime + $min2); |
||
850 | return; |
||
851 | } |
||
852 | case DateDefinitions::DAY_OF_WEEK: |
||
853 | case DateDefinitions::DOW_LOCAL: |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
854 | { |
||
855 | // Roll the day of week using millis. Compute the millis for |
||
856 | // the start of the week, using the first day of week setting. |
||
857 | // Restrict the millis to [start, start+7days). |
||
858 | $delta = (float) ($amount * DateDefinitions::MILLIS_PER_DAY); // Scale up from days to millis |
||
859 | // Compute the number of days before the current day in this |
||
860 | // week. This will be a value 0..6. |
||
861 | $leadDays = $this->internalGet($field); |
||
862 | $leadDays -= ($field == DateDefinitions::DAY_OF_WEEK) ? $this->getFirstDayOfWeek() : 1; |
||
863 | if ($leadDays < 0) { |
||
864 | $leadDays += 7; |
||
865 | } |
||
866 | $min2 = (float) ($this->internalGetTime() - $leadDays * DateDefinitions::MILLIS_PER_DAY); |
||
867 | $newtime = fmod(($this->internalGetTime() + $delta - $min2), DateDefinitions::MILLIS_PER_WEEK); |
||
868 | if ($newtime < 0) { |
||
869 | $newtime += DateDefinitions::MILLIS_PER_WEEK; |
||
870 | } |
||
871 | $this->setTimeInMillis($newtime + $min2); |
||
872 | return; |
||
873 | } |
||
874 | case DateDefinitions::DAY_OF_WEEK_IN_MONTH: |
||
0 ignored issues
–
show
case statements should be defined using a colon.
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces.
There is no need for braces, since each case is terminated by the next There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages. switch ($expr) {
case "A": { //wrong
doSomething();
break;
}
case "B"; //wrong
doSomething();
break;
case "C": //right
doSomething();
break;
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
875 | { |
||
876 | // Roll the day of week in the month using millis. Determine |
||
877 | // the first day of the week in the month, and then the last, |
||
878 | // and then roll within that range. |
||
879 | $delta = (float) ($amount * DateDefinitions::MILLIS_PER_WEEK); // Scale up from weeks to millis |
||
880 | // Find the number of same days of the week before this one |
||
881 | // in this month. |
||
882 | $preWeeks = (int) (($this->internalGet(DateDefinitions::DAY_OF_MONTH) - 1) / 7); |
||
883 | // Find the number of same days of the week after this one |
||
884 | // in this month. |
||
885 | $postWeeks = (int) (($this->getActualMaximum(DateDefinitions::DAY_OF_MONTH) - $this->internalGet(DateDefinitions::DAY_OF_MONTH)) / 7); |
||
886 | // From these compute the min and gap millis for rolling. |
||
887 | $min2 = (float) ($this->internalGetTime() - $preWeeks * DateDefinitions::MILLIS_PER_WEEK); |
||
888 | $gap2 = (float) (DateDefinitions::MILLIS_PER_WEEK * ($preWeeks + $postWeeks + 1)); // Must add 1! |
||
889 | // Roll within this range |
||
890 | $newtime = fmod(($this->internalGetTime() + $delta - $min2), $gap2); |
||
891 | if ($newtime < 0) { |
||
892 | $newtime += $gap2; |
||
893 | } |
||
894 | $this->setTimeInMillis($newtime + $min2); |
||
895 | return; |
||
896 | } |
||
897 | case DateDefinitions::JULIAN_DAY: |
||
898 | $this->set($field, $this->internalGet($field) + $amount); |
||
899 | return; |
||
900 | default: |
||
901 | // Other fields cannot be rolled by this method |
||
902 | throw new \InvalidArgumentException('Calendar::roll(): field ' . $field . ' cannot be rolled with this method'); |
||
903 | } |
||
904 | } |
||
905 | |||
906 | /** |
||
907 | * Return the difference between the given time and the time this |
||
908 | * calendar object is set to. If this calendar is set |
||
909 | * <em>before</em> the given time, the returned value will be |
||
910 | * positive. If this calendar is set <em>after</em> the given |
||
911 | * time, the returned value will be negative. The |
||
912 | * <code>field</code> parameter specifies the units of the return |
||
913 | * value. For example, if <code>fieldDifference($when, |
||
914 | * DateDefinitions::MONTH)</code> returns 3, then this calendar is set to |
||
915 | * 3 months before <code>when</code>, and possibly some addition |
||
916 | * time less than one month. |
||
917 | * |
||
918 | * <p>As a side effect of this call, this calendar is advanced |
||
919 | * toward <code>$when</code> by the given amount. That is, calling |
||
920 | * this method has the side effect of calling <code>add($field, |
||
921 | * $n)</code>, where <code>n</code> is the return value. |
||
922 | * |
||
923 | * <p>Usage: To use this method, call it first with the largest |
||
924 | * field of interest, then with progressively smaller fields. For |
||
925 | * example: |
||
926 | * |
||
927 | * <pre> |
||
928 | * $y = $cal->fieldDifference($when, DateDefinitions::YEAR); |
||
929 | * $m = $cal->fieldDifference($when, DateDefinitions::MONTH); |
||
930 | * $d = $cal->fieldDifference($when, DateDefinitions::DATE);</pre> |
||
931 | * |
||
932 | * computes the difference between <code>$cal</code> and |
||
933 | * <code>$when</code> in years, months, and days. |
||
934 | * |
||
935 | * <p>Note: <code>fieldDifference()</code> is |
||
936 | * <em>asymmetrical</em>. That is, in the following code: |
||
937 | * |
||
938 | * <pre> |
||
939 | * $cal->setTime($date1); |
||
940 | * $m1 = $cal->fieldDifference($date2, DateDefinitions::MONTH); |
||
941 | * $d1 = $cal->fieldDifference($date2, DateDefinitions::DATE); |
||
942 | * $cal->setTime($date2); |
||
943 | * $m2 = $cal->fieldDifference($date1, DateDefinitions::MONTH); |
||
944 | * $d2 = $cal->fieldDifference($date1, DateDefinitions::DATE);</pre> |
||
945 | * |
||
946 | * one might expect that <code>$m1 == -$m2 && $d1 == -$d2</code>. |
||
947 | * However, this is not generally the case, because of |
||
948 | * irregularities in the underlying calendar system (e.g., the |
||
949 | * Gregorian calendar has a varying number of days per month). |
||
950 | * |
||
951 | * @param float|Calendar $targetMs When the date to compare this |
||
952 | * calendar's time to |
||
953 | * @param int $field The field in which to compute the result |
||
954 | * |
||
955 | * @return int The difference, either positive or negative, between |
||
956 | * this calendar's time and <code>when</code>, in terms |
||
957 | * of <code>field</code>. |
||
958 | * |
||
959 | * @author Dominik del Bondio <[email protected]> |
||
960 | * @author The ICU Project |
||
961 | * @since 0.11.0 |
||
962 | */ |
||
963 | public function fieldDifference($targetMs /* $when */, $field) |
||
964 | { |
||
965 | $min = 0; |
||
966 | $startMs = (float) $this->getTimeInMillis(); |
||
967 | if ($targetMs instanceof Calendar) { |
||
968 | $targetMs = (float) $targetMs->getTimeInMillis(); |
||
969 | } |
||
970 | // Always add from the start millis. This accommodates |
||
971 | // operations like adding years from February 29, 2000 up to |
||
972 | // February 29, 2004. If 1, 1, 1, 1 is added to the year |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
37% 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. ![]() |
|||
973 | // field, the DOM gets pinned to 28 and stays there, giving an |
||
974 | // incorrect DOM difference of 1. We have to add 1, reset, 2, |
||
975 | // reset, 3, reset, 4. |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
46% 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. ![]() |
|||
976 | if ($startMs < $targetMs) { |
||
977 | $max = 1; |
||
978 | // Find a value that is too large |
||
979 | View Code Duplication | while (true) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
980 | $this->setTimeInMillis($startMs); |
||
981 | $this->add($field, $max); |
||
982 | $ms = (float) $this->getTimeInMillis(); |
||
983 | if ($ms == $targetMs) { |
||
984 | return $max; |
||
985 | } elseif ($ms > $targetMs) { |
||
986 | break; |
||
987 | } else { |
||
988 | $max <<= 1; |
||
989 | if ($max < 0) { |
||
990 | // TODO: check if we can change this to float to support a larger range |
||
991 | // Field difference too large to fit into int32_t |
||
992 | throw new \InvalidArgumentException('The difference is to large to fit into an integer'); |
||
993 | } |
||
994 | } |
||
995 | } |
||
996 | // Do a binary search |
||
997 | View Code Duplication | while (($max - $min) > 1) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
998 | $t = (int) (($min + $max) / 2); |
||
999 | $this->setTimeInMillis($startMs); |
||
1000 | $this->add($field, $t); |
||
1001 | $ms = (float) $this->getTimeInMillis(); |
||
1002 | if ($ms == $targetMs) { |
||
1003 | return $t; |
||
1004 | } elseif ($ms > $targetMs) { |
||
1005 | $max = $t; |
||
1006 | } else { |
||
1007 | $min = $t; |
||
1008 | } |
||
1009 | } |
||
1010 | } elseif ($startMs > $targetMs) { |
||
1011 | $max = -1; |
||
1012 | // Find a value that is too small |
||
1013 | View Code Duplication | while (true) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1014 | $this->setTimeInMillis($startMs); |
||
1015 | $this->add($field, $max); |
||
1016 | $ms = (float) $this->getTimeInMillis(); |
||
1017 | if ($ms == $targetMs) { |
||
1018 | return $max; |
||
1019 | } elseif ($ms < $targetMs) { |
||
1020 | break; |
||
1021 | } else { |
||
1022 | $max <<= 1; |
||
1023 | if ($max == 0) { |
||
1024 | // TODO: see above |
||
1025 | // Field difference too large to fit into int32_t |
||
1026 | throw new \InvalidArgumentException('The difference is to large to fit into an integer'); |
||
1027 | } |
||
1028 | } |
||
1029 | } |
||
1030 | // Do a binary search |
||
1031 | View Code Duplication | while (($min - $max) > 1) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1032 | $t = (int) (($min + $max) / 2); |
||
1033 | $this->setTimeInMillis($startMs); |
||
1034 | $this->add($field, $t); |
||
1035 | $ms = (float) $this->getTimeInMillis(); |
||
1036 | if ($ms == $targetMs) { |
||
1037 | return $t; |
||
1038 | } elseif ($ms < $targetMs) { |
||
1039 | $max = $t; |
||
1040 | } else { |
||
1041 | $min = $t; |
||
1042 | } |
||
1043 | } |
||
1044 | } |
||
1045 | // Set calendar to end point |
||
1046 | $this->setTimeInMillis($startMs); |
||
1047 | $this->add($field, $min); |
||
1048 | |||
1049 | return $min; |
||
1050 | } |
||
1051 | |||
1052 | /** |
||
1053 | * Sets the calendar's time zone to be the same as the one passed in. The |
||
1054 | * TimeZone passed in is _not_ cloned. |
||
1055 | * |
||
1056 | * @param TimeZone $zone The given time zone. If null is passed nothing |
||
1057 | * is done. |
||
1058 | * |
||
1059 | * @author Dominik del Bondio <[email protected]> |
||
1060 | * @author The ICU Project |
||
1061 | * @since 0.11.0 |
||
1062 | */ |
||
1063 | public function setTimeZone(TimeZone $zone = null) |
||
1064 | { |
||
1065 | // Do nothing if passed-in zone is NULL |
||
1066 | if (!$zone) { |
||
1067 | return; |
||
1068 | } |
||
1069 | |||
1070 | // fZone should always be non-null |
||
1071 | $this->fZone = $zone; |
||
1072 | |||
1073 | // if the zone changes, we need to recompute the time fields |
||
1074 | $this->fAreFieldsInSync = false; |
||
1075 | } |
||
1076 | |||
1077 | /** |
||
1078 | * Returns a reference to the time zone owned by this calendar. |
||
1079 | * |
||
1080 | * @return TimeZone The time zone object associated with this |
||
1081 | * calendar. |
||
1082 | * |
||
1083 | * @author Dominik del Bondio <[email protected]> |
||
1084 | * @author The ICU Project |
||
1085 | * @since 0.11.0 |
||
1086 | */ |
||
1087 | public function getTimeZone() |
||
1088 | { |
||
1089 | return $this->fZone; |
||
1090 | } |
||
1091 | |||
1092 | /** |
||
1093 | * Queries if the current date for this Calendar is in Daylight Savings Time. |
||
1094 | * |
||
1095 | * @return bool True if the current date for this Calendar is in |
||
1096 | * Daylight Savings Time, false, otherwise. |
||
1097 | * |
||
1098 | * @author Dominik del Bondio <[email protected]> |
||
1099 | * @author The ICU Project |
||
1100 | * @since 0.11.0 |
||
1101 | */ |
||
1102 | abstract public function inDaylightTime(); |
||
1103 | |||
1104 | /** |
||
1105 | * Specifies whether or not date/time interpretation is to be lenient. With |
||
1106 | * lenient interpretation, a date such as "February 942, 1996" will be treated |
||
1107 | * as being equivalent to the 941st day after February 1, 1996. With strict |
||
1108 | * interpretation, such dates will cause an error when computing time from the |
||
1109 | * time field values representing the dates. |
||
1110 | * |
||
1111 | * @param bool $lenient True specifies date/time interpretation to be lenient. |
||
1112 | * |
||
1113 | * @author Dominik del Bondio <[email protected]> |
||
1114 | * @author The ICU Project |
||
1115 | * @since 0.11.0 |
||
1116 | */ |
||
1117 | public function setLenient($lenient) |
||
1118 | { |
||
1119 | $this->fLenient = $lenient; |
||
1120 | } |
||
1121 | |||
1122 | /** |
||
1123 | * Tells whether date/time interpretation is to be lenient. |
||
1124 | * |
||
1125 | * @return bool True tells that date/time interpretation is to be lenient. |
||
1126 | * |
||
1127 | * @author Dominik del Bondio <[email protected]> |
||
1128 | * @author The ICU Project |
||
1129 | * @since 0.11.0 |
||
1130 | */ |
||
1131 | public function isLenient() |
||
1132 | { |
||
1133 | return $this->fLenient; |
||
1134 | } |
||
1135 | |||
1136 | /** |
||
1137 | * Sets what the first day of the week is; e.g., Sunday in US, Monday in |
||
1138 | * France. |
||
1139 | * |
||
1140 | * @param int $value The given first day of the week. |
||
1141 | * |
||
1142 | * @author Dominik del Bondio <[email protected]> |
||
1143 | * @author The ICU Project |
||
1144 | * @since 0.11.0 |
||
1145 | */ |
||
1146 | public function setFirstDayOfWeek($value) |
||
1147 | { |
||
1148 | $this->fFirstDayOfWeek = $value; |
||
1149 | } |
||
1150 | |||
1151 | /** |
||
1152 | * Gets what the first day of the week is; e.g., Sunday in US, Monday in |
||
1153 | * France. |
||
1154 | * |
||
1155 | * @return int The first day of the week. |
||
1156 | * |
||
1157 | * @author Dominik del Bondio <[email protected]> |
||
1158 | * @author The ICU Project |
||
1159 | * @since 0.11.0 |
||
1160 | */ |
||
1161 | public function getFirstDayOfWeek() |
||
1162 | { |
||
1163 | return $this->fFirstDayOfWeek; |
||
1164 | } |
||
1165 | |||
1166 | /** |
||
1167 | * Sets what the minimal days required in the first week of the year are; For |
||
1168 | * example, if the first week is defined as one that contains the first day of |
||
1169 | * the first month of a year, call the method with value 1. If it must be a |
||
1170 | * full week, use value 7. |
||
1171 | * |
||
1172 | * @param int $value The given minimal days required in the first week of the |
||
1173 | * year. |
||
1174 | * |
||
1175 | * @author Dominik del Bondio <[email protected]> |
||
1176 | * @author The ICU Project |
||
1177 | * @since 0.11.0 |
||
1178 | */ |
||
1179 | public function setMinimalDaysInFirstWeek($value) |
||
1180 | { |
||
1181 | $this->fMinimalDaysInFirstWeek = $value; |
||
1182 | } |
||
1183 | |||
1184 | /** |
||
1185 | * Gets what the minimal days required in the first week of the year are; |
||
1186 | * e.g., if the first week is defined as one that contains the first day of |
||
1187 | * the first month of a year, getMinimalDaysInFirstWeek returns 1. If the |
||
1188 | * minimal days required must be a full week, getMinimalDaysInFirstWeek |
||
1189 | * returns 7. |
||
1190 | * |
||
1191 | * @return int The minimal days required in the first week of the year. |
||
1192 | * |
||
1193 | * @author Dominik del Bondio <[email protected]> |
||
1194 | * @author The ICU Project |
||
1195 | * @since 0.11.0 |
||
1196 | */ |
||
1197 | public function getMinimalDaysInFirstWeek() |
||
1198 | { |
||
1199 | return $this->fMinimalDaysInFirstWeek; |
||
1200 | } |
||
1201 | |||
1202 | /** |
||
1203 | * Gets the minimum value for the given time field. e.g., for Gregorian |
||
1204 | * DAY_OF_MONTH, 1. |
||
1205 | * |
||
1206 | * @param int $field The given time field. |
||
1207 | * |
||
1208 | * @return int The minimum value for the given time field. |
||
1209 | * |
||
1210 | * @author Dominik del Bondio <[email protected]> |
||
1211 | * @author The ICU Project |
||
1212 | * @since 0.11.0 |
||
1213 | */ |
||
1214 | public function getMinimum($field) |
||
1215 | { |
||
1216 | return $this->getLimit($field, self::LIMIT_MINIMUM); |
||
1217 | } |
||
1218 | |||
1219 | /** |
||
1220 | * Gets the maximum value for the given time field. e.g., for Gregorian |
||
1221 | * DAY_OF_MONTH, 31. |
||
1222 | * |
||
1223 | * @param int $field The given time field. |
||
1224 | * |
||
1225 | * @return int The maximum value for the given time field. |
||
1226 | * |
||
1227 | * @author Dominik del Bondio <[email protected]> |
||
1228 | * @author The ICU Project |
||
1229 | * @since 0.11.0 |
||
1230 | */ |
||
1231 | public function getMaximum($field) |
||
1232 | { |
||
1233 | return $this->getLimit($field, self::LIMIT_MAXIMUM); |
||
1234 | } |
||
1235 | |||
1236 | /** |
||
1237 | * Gets the highest minimum value for the given field if varies. Otherwise |
||
1238 | * same as getMinimum(). For Gregorian, no difference. |
||
1239 | * |
||
1240 | * @param int $field The given time field. |
||
1241 | * |
||
1242 | * @return int The highest minimum value for the given time field. |
||
1243 | * |
||
1244 | * @author Dominik del Bondio <[email protected]> |
||
1245 | * @author The ICU Project |
||
1246 | * @since 0.11.0 |
||
1247 | */ |
||
1248 | public function getGreatestMinimum($field) |
||
1249 | { |
||
1250 | return $this->getLimit($field, self::LIMIT_GREATEST_MINIMUM); |
||
1251 | } |
||
1252 | |||
1253 | /** |
||
1254 | * Gets the lowest maximum value for the given field if varies. Otherwise same |
||
1255 | * as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28. |
||
1256 | * |
||
1257 | * @param int $field The given time field. |
||
1258 | * |
||
1259 | * @return int The lowest maximum value for the given time field. |
||
1260 | * |
||
1261 | * @author Dominik del Bondio <[email protected]> |
||
1262 | * @author The ICU Project |
||
1263 | * @since 0.11.0 |
||
1264 | */ |
||
1265 | public function getLeastMaximum($field) |
||
1266 | { |
||
1267 | return $this->getLimit($field, self::LIMIT_LEAST_MAXIMUM); |
||
1268 | } |
||
1269 | |||
1270 | /** |
||
1271 | * Return the minimum value that this field could have, given the current |
||
1272 | * date. For the Gregorian calendar, this is the same as getMinimum() and |
||
1273 | * getGreatestMinimum(). |
||
1274 | * |
||
1275 | * The version of this function on Calendar uses an iterative algorithm to |
||
1276 | * determine the actual minimum value for the field. There is almost always a |
||
1277 | * more efficient way to accomplish this (in most cases, you can simply return |
||
1278 | * getMinimum()). GregorianCalendar overrides this function with a more |
||
1279 | * efficient implementation. |
||
1280 | * |
||
1281 | * @param int $field the field to determine the minimum of |
||
1282 | * |
||
1283 | * @return int the minimum of the given field for the current date of |
||
1284 | * this Calendar |
||
1285 | * |
||
1286 | * @author Dominik del Bondio <[email protected]> |
||
1287 | * @author The ICU Project |
||
1288 | * @since 0.11.0 |
||
1289 | */ |
||
1290 | public function getActualMinimum($field) |
||
1291 | { |
||
1292 | $fieldValue = $this->getGreatestMinimum($field); |
||
1293 | $endValue = $this->getMinimum($field); |
||
1294 | |||
1295 | // if we know that the minimum value is always the same, just return it |
||
1296 | if ($fieldValue == $endValue) { |
||
1297 | return $fieldValue; |
||
1298 | } |
||
1299 | |||
1300 | // clone the calendar so we don't mess with the real one, and set it to |
||
1301 | // accept anything for the field values |
||
1302 | $work = clone $this; |
||
1303 | $work->setLenient(true); |
||
1304 | |||
1305 | // now try each value from getLeastMaximum() to getMaximum() one by one until |
||
1306 | // we get a value that normalizes to another value. The last value that |
||
1307 | // normalizes to itself is the actual minimum for the current date |
||
1308 | $result = $fieldValue; |
||
1309 | |||
1310 | View Code Duplication | do { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1311 | $work->set($field, $fieldValue); |
||
1312 | if ($work->get($field) != $fieldValue) { |
||
1313 | break; |
||
1314 | } else { |
||
1315 | $result = $fieldValue; |
||
1316 | $fieldValue--; |
||
1317 | } |
||
1318 | } while ($fieldValue >= $endValue); |
||
1319 | |||
1320 | return $result; |
||
1321 | } |
||
1322 | |||
1323 | /** |
||
1324 | * Return the maximum value that this field could have, given the current |
||
1325 | * date. For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, |
||
1326 | * the actual maximum would be 28; for "Feb 3, 1996" it s 29. Similarly for a |
||
1327 | * Hebrew calendar,for some years the actual maximum for MONTH is 12, and for |
||
1328 | * others 13. |
||
1329 | * |
||
1330 | * The version of this function on Calendar uses an iterative algorithm to |
||
1331 | * determine the actual maximum value for the field. There is almost always a |
||
1332 | * more efficient way to accomplish this (in most cases, you can simply return |
||
1333 | * getMaximum()). AgaviGregorianCalendar overrides this function with a more |
||
1334 | * efficient implementation. |
||
1335 | * |
||
1336 | * @param int $field the field to determine the maximum of |
||
1337 | * |
||
1338 | * @return int the maximum of the given field for the current date of |
||
1339 | * this Calendar |
||
1340 | * |
||
1341 | * @author Dominik del Bondio <[email protected]> |
||
1342 | * @author The ICU Project |
||
1343 | * @since 0.11.0 |
||
1344 | */ |
||
1345 | public function getActualMaximum($field) |
||
1346 | { |
||
1347 | switch ($field) { |
||
1348 | View Code Duplication | case DateDefinitions::DATE: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1349 | $cal = clone $this; |
||
1350 | $cal->prepareGetActual($field, false); |
||
1351 | $result = $this->handleGetMonthLength($cal->get(DateDefinitions::EXTENDED_YEAR), $cal->get(DateDefinitions::MONTH)); |
||
1352 | break; |
||
1353 | |||
1354 | View Code Duplication | case DateDefinitions::DAY_OF_YEAR: |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1355 | $cal = clone $this; |
||
1356 | $cal->prepareGetActual($field, false); |
||
1357 | $result = $this->handleGetYearLength($cal->get(DateDefinitions::EXTENDED_YEAR)); |
||
1358 | break; |
||
1359 | |||
1360 | case DateDefinitions::DAY_OF_WEEK: |
||
1361 | case DateDefinitions::AM_PM: |
||
1362 | case DateDefinitions::HOUR: |
||
1363 | case DateDefinitions::HOUR_OF_DAY: |
||
1364 | case DateDefinitions::MINUTE: |
||
1365 | case DateDefinitions::SECOND: |
||
1366 | case DateDefinitions::MILLISECOND: |
||
1367 | case DateDefinitions::ZONE_OFFSET: |
||
1368 | case DateDefinitions::DST_OFFSET: |
||
1369 | case DateDefinitions::DOW_LOCAL: |
||
1370 | case DateDefinitions::JULIAN_DAY: |
||
1371 | case DateDefinitions::MILLISECONDS_IN_DAY: |
||
1372 | // These fields all have fixed minima/maxima |
||
1373 | $result = $this->getMaximum($field); |
||
1374 | break; |
||
1375 | |||
1376 | default: |
||
1377 | // For all other fields, do it the hard way.... |
||
1378 | $result = $this->getActualHelper($field, $this->getLeastMaximum($field), $this->getMaximum($field)); |
||
1379 | break; |
||
1380 | } |
||
1381 | return $result; |
||
1382 | } |
||
1383 | |||
1384 | /** |
||
1385 | * Gets all time field values. Recalculate the current time field |
||
1386 | * values if the time value has been changed by a call to setTime(). Return |
||
1387 | * zero for unset fields if any fields have been explicitly set by a call to |
||
1388 | * set(). To force a recomputation of all fields regardless of the previous |
||
1389 | * state, call complete(). |
||
1390 | * |
||
1391 | * @return array All fields of this instance. |
||
1392 | * |
||
1393 | * @author Dominik del Bondio <[email protected]> |
||
1394 | * @author The ICU Project |
||
1395 | * @since 0.11.0 |
||
1396 | */ |
||
1397 | public function getAll() |
||
1398 | { |
||
1399 | // field values are only computed when actually requested; for more on when computation |
||
1400 | // of various things happens, see the "data flow in Calendar" description at the top |
||
1401 | // of this file |
||
1402 | $this->complete(); |
||
1403 | return $this->fFields; |
||
1404 | } |
||
1405 | |||
1406 | /** |
||
1407 | * Gets the value for a given time field. Recalculate the current time field |
||
1408 | * values if the time value has been changed by a call to setTime(). Return |
||
1409 | * zero for unset fields if any fields have been explicitly set by a call to |
||
1410 | * set(). To force a recomputation of all fields regardless of the previous |
||
1411 | * state, call complete(). |
||
1412 | * |
||
1413 | * @param int $field The given time field. |
||
1414 | * |
||
1415 | * @return int The value for the given time field, or zero if the field |
||
1416 | * is unset, and set() has been called for any other field. |
||
1417 | * |
||
1418 | * @author Dominik del Bondio <[email protected]> |
||
1419 | * @author The ICU Project |
||
1420 | * @since 0.11.0 |
||
1421 | */ |
||
1422 | public function get($field) |
||
1423 | { |
||
1424 | // field values are only computed when actually requested; for more on when computation |
||
1425 | // of various things happens, see the "data flow in Calendar" description at the top |
||
1426 | // of this file |
||
1427 | $this->complete(); |
||
1428 | return $this->fFields[$field]; |
||
1429 | } |
||
1430 | |||
1431 | /** |
||
1432 | * Determines if the given time field has a value set. This can affect in the |
||
1433 | * resolving of time in Calendar. Unset fields have a value of zero, by |
||
1434 | * definition. |
||
1435 | * |
||
1436 | * @param int $field The given time field. |
||
1437 | * |
||
1438 | * @return bool True if the given time field has a value set; false |
||
1439 | * otherwise. |
||
1440 | * |
||
1441 | * @author Dominik del Bondio <[email protected]> |
||
1442 | * @author The ICU Project |
||
1443 | * @since 0.11.0 |
||
1444 | */ |
||
1445 | public function _isSet($field) // isset is a keyword in php |
||
1446 | { |
||
1447 | return $this->fAreFieldsVirtuallySet || ($this->fStamp[$field] != self::kUnset); |
||
1448 | } |
||
1449 | |||
1450 | /** |
||
1451 | * Overloaded |
||
1452 | * |
||
1453 | * @see Calendar::set1() |
||
1454 | * @see Calendar::set2() |
||
1455 | * @see Calendar::set3() |
||
1456 | * @see Calendar::set4() |
||
1457 | * |
||
1458 | * @author Dominik del Bondio <[email protected]> |
||
1459 | * @author The ICU Project |
||
1460 | * @since 0.11.0 |
||
1461 | */ |
||
1462 | public function set() |
||
1463 | { |
||
1464 | $arguments = func_get_args(); |
||
1465 | |||
1466 | $fName = Toolkit::overloadHelper(array( |
||
1467 | array('name' => 'set1', |
||
1468 | 'parameters' => array('int', 'int')), |
||
1469 | array('name' => 'set2', |
||
1470 | 'parameters' => array('int', 'int', 'int')), |
||
1471 | array('name' => 'set3', |
||
1472 | 'parameters' => array('int', 'int', 'int', 'int', 'int')), |
||
1473 | array('name' => 'set4', |
||
1474 | 'parameters' => array('int', 'int', 'int', 'int', 'int', 'int')), |
||
1475 | ), |
||
1476 | $arguments |
||
1477 | ); |
||
1478 | call_user_func_array(array($this, $fName), $arguments); |
||
1479 | } |
||
1480 | |||
1481 | /** |
||
1482 | * Sets the given time field with the given value. |
||
1483 | * |
||
1484 | * @param int $field The given time field. |
||
1485 | * @param int $value The value to be set for the given time field. |
||
1486 | * |
||
1487 | * @author Dominik del Bondio <[email protected]> |
||
1488 | * @author The ICU Project |
||
1489 | * @since 0.11.0 |
||
1490 | */ |
||
1491 | View Code Duplication | public function set1($field, $value) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1492 | { |
||
1493 | if ($this->fAreFieldsVirtuallySet) { |
||
1494 | $this->computeFields(); |
||
1495 | } |
||
1496 | |||
1497 | $this->fFields[$field] = $value; |
||
1498 | $this->fStamp[$field] = $this->fNextStamp++; |
||
1499 | $this->fIsSet[$field] = true; // Remove later |
||
0 ignored issues
–
show
The property
Agavi\Date\Calendar::$fIsSet has been deprecated with message: ICU 2.8 use (fStamp[n]!=kUnset)
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
|||
1500 | $this->fIsTimeSet = $this->fAreFieldsInSync = $this->fAreFieldsVirtuallySet = false; |
||
1501 | } |
||
1502 | |||
1503 | /** |
||
1504 | * Sets the values for the fields YEAR, MONTH, and DATE. Other field values |
||
1505 | * are retained; call clear() first if this is not desired. |
||
1506 | * |
||
1507 | * @param int $year The value used to set the YEAR time field. |
||
1508 | * @param int $month The value used to set the MONTH time field. Month value is |
||
1509 | * 0-based. e.g., 0 for January. |
||
1510 | * @param int $date The value used to set the DATE time field. |
||
1511 | * |
||
1512 | * @author Dominik del Bondio <[email protected]> |
||
1513 | * @author The ICU Project |
||
1514 | * @since 0.11.0 |
||
1515 | */ |
||
1516 | public function set2($year, $month, $date) |
||
1517 | { |
||
1518 | $this->set1(DateDefinitions::YEAR, $year); |
||
1519 | $this->set1(DateDefinitions::MONTH, $month); |
||
1520 | $this->set1(DateDefinitions::DATE, $date); |
||
1521 | } |
||
1522 | |||
1523 | /** |
||
1524 | * Sets the values for the fields YEAR, MONTH, DATE, HOUR_OF_DAY, and MINUTE. |
||
1525 | * Other field values are retained; call |
||
1526 | * ) first if this is not desired. |
||
1527 | * |
||
1528 | * @param int $year The value used to set the YEAR time field. |
||
1529 | * @param int $month The value used to set the MONTH time field. Month value is |
||
1530 | * 0-based. E.g., 0 for January. |
||
1531 | * @param int $date The value used to set the DATE time field. |
||
1532 | * @param int $hour The value used to set the HOUR_OF_DAY time field. |
||
1533 | * @param int $minute The value used to set the MINUTE time field. |
||
1534 | * |
||
1535 | * @author Dominik del Bondio <[email protected]> |
||
1536 | * @author The ICU Project |
||
1537 | * @since 0.11.0 |
||
1538 | */ |
||
1539 | View Code Duplication | public function set3($year, $month, $date, $hour, $minute) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1540 | { |
||
1541 | $this->set1(DateDefinitions::YEAR, $year); |
||
1542 | $this->set1(DateDefinitions::MONTH, $month); |
||
1543 | $this->set1(DateDefinitions::DATE, $date); |
||
1544 | $this->set1(DateDefinitions::HOUR_OF_DAY, $hour); |
||
1545 | $this->set1(DateDefinitions::MINUTE, $minute); |
||
1546 | } |
||
1547 | |||
1548 | /** |
||
1549 | * Sets the values for the fields YEAR, MONTH, DATE, HOUR_OF_DAY, MINUTE, and |
||
1550 | * SECOND. Other field values are retained; call clear() first if this is not |
||
1551 | * desired. |
||
1552 | * |
||
1553 | * @param int $year The value used to set the YEAR time field. |
||
1554 | * @param int $month The value used to set the MONTH time field. Month value is |
||
1555 | * 0-based. E.g., 0 for January. |
||
1556 | * @param int $date The value used to set the DATE time field. |
||
1557 | * @param int $hour The value used to set the HOUR_OF_DAY time field. |
||
1558 | * @param int $minute The value used to set the MINUTE time field. |
||
1559 | * @param int $second The value used to set the SECOND time field. |
||
1560 | * |
||
1561 | * @author Dominik del Bondio <[email protected]> |
||
1562 | * @author The ICU Project |
||
1563 | * @since 0.11.0 |
||
1564 | */ |
||
1565 | View Code Duplication | public function set4($year, $month, $date, $hour, $minute, $second) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1566 | { |
||
1567 | $this->set1(DateDefinitions::YEAR, $year); |
||
1568 | $this->set1(DateDefinitions::MONTH, $month); |
||
1569 | $this->set1(DateDefinitions::DATE, $date); |
||
1570 | $this->set1(DateDefinitions::HOUR_OF_DAY, $hour); |
||
1571 | $this->set1(DateDefinitions::MINUTE, $minute); |
||
1572 | $this->set1(DateDefinitions::SECOND, $second); |
||
1573 | } |
||
1574 | |||
1575 | /** |
||
1576 | * Overloaded |
||
1577 | * |
||
1578 | * @see Calendar::clear1() |
||
1579 | * @see Calendar::clear2() |
||
1580 | * |
||
1581 | * @author Dominik del Bondio <[email protected]> |
||
1582 | * @author The ICU Project |
||
1583 | * @since 0.11.0 |
||
1584 | */ |
||
1585 | public function clear() |
||
1586 | { |
||
1587 | $arguments = func_get_args(); |
||
1588 | |||
1589 | $fName = Toolkit::overloadHelper(array( |
||
1590 | array('name' => 'clear1', |
||
1591 | 'parameters' => array()), |
||
1592 | array('name' => 'clear2', |
||
1593 | 'parameters' => array('int')), |
||
1594 | ), |
||
1595 | $arguments |
||
1596 | ); |
||
1597 | call_user_func_array(array($this, $fName), $arguments); |
||
1598 | } |
||
1599 | |||
1600 | /** |
||
1601 | * Clears the values of all the time fields, making them both unset and |
||
1602 | * assigning them a value of zero. The field values will be determined during |
||
1603 | * the next resolving of time into time fields. |
||
1604 | * |
||
1605 | * @author Dominik del Bondio <[email protected]> |
||
1606 | * @author The ICU Project |
||
1607 | * @since 0.11.0 |
||
1608 | */ |
||
1609 | public function clear1() |
||
1610 | { |
||
1611 | for ($i = 0; $i < DateDefinitions::FIELD_COUNT; ++$i) { |
||
1612 | $this->fFields[$i] = 0; // Must do this; other code depends on it |
||
1613 | $this->fStamp[$i] = self::kUnset; |
||
1614 | $this->fIsSet[$i] = false; // Remove later |
||
0 ignored issues
–
show
The property
Agavi\Date\Calendar::$fIsSet has been deprecated with message: ICU 2.8 use (fStamp[n]!=kUnset)
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
|||
1615 | } |
||
1616 | $this->fIsTimeSet = $this->fAreFieldsInSync = $this->fAreAllFieldsSet = $this->fAreFieldsVirtuallySet = false; |
||
1617 | // fTime is not 'cleared' - may be used if no fields are set. |
||
1618 | } |
||
1619 | |||
1620 | /** |
||
1621 | * Clears the value in the given time field, both making it unset and |
||
1622 | * assigning it a value of zero. This field value will be determined during |
||
1623 | * the next resolving of time into time fields. |
||
1624 | * |
||
1625 | * @param string $field The time field to be cleared. |
||
1626 | * |
||
1627 | * @author Dominik del Bondio <[email protected]> |
||
1628 | * @author The ICU Project |
||
1629 | * @since 0.11.0 |
||
1630 | */ |
||
1631 | View Code Duplication | public function clear2($field) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1632 | { |
||
1633 | if ($this->fAreFieldsVirtuallySet) { |
||
1634 | $this->computeFields(); |
||
1635 | } |
||
1636 | $this->fFields[$field] = 0; |
||
1637 | $this->fStamp[$field] = self::kUnset; |
||
1638 | $this->fIsSet[$field] = false; // Remove later |
||
0 ignored issues
–
show
The property
Agavi\Date\Calendar::$fIsSet has been deprecated with message: ICU 2.8 use (fStamp[n]!=kUnset)
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
|||
1639 | $this->fIsTimeSet = $this->fAreFieldsInSync = $this->fAreAllFieldsSet = $this->fAreFieldsVirtuallySet = false; |
||
1640 | } |
||
1641 | |||
1642 | /** |
||
1643 | * Converts Calendar's time field values to GMT as milliseconds. |
||
1644 | * |
||
1645 | * @author Dominik del Bondio <[email protected]> |
||
1646 | * @author The ICU Project |
||
1647 | * @since 0.11.0 |
||
1648 | */ |
||
1649 | protected function computeTime() |
||
1650 | { |
||
1651 | if (!$this->isLenient()) { |
||
1652 | $this->validateFields(); |
||
1653 | } |
||
1654 | |||
1655 | // Compute the Julian day |
||
1656 | $julianDay = $this->computeJulianDay(); |
||
1657 | |||
1658 | $millis = CalendarGrego::julianDayToMillis($julianDay); |
||
1659 | |||
1660 | $millisInDay = 0; |
||
0 ignored issues
–
show
$millisInDay 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 ![]() |
|||
1661 | |||
1662 | // We only use MILLISECONDS_IN_DAY if it has been set by the user. |
||
1663 | // This makes it possible for the caller to set the calendar to a |
||
1664 | // time and call clear(MONTH) to reset the MONTH to January. This |
||
1665 | // is legacy behavior. Without this, clear(MONTH) has no effect, |
||
1666 | // since the internally set JULIAN_DAY is used. |
||
1667 | if ($this->fStamp[DateDefinitions::MILLISECONDS_IN_DAY] >= (self::kMinimumUserStamp) && |
||
1668 | $this->newestStamp(DateDefinitions::AM_PM, DateDefinitions::MILLISECOND, self::kUnset) <= $this->fStamp[DateDefinitions::MILLISECONDS_IN_DAY]) { |
||
1669 | $millisInDay = $this->internalGet(DateDefinitions::MILLISECONDS_IN_DAY); |
||
1670 | } else { |
||
1671 | $millisInDay = $this->computeMillisInDay(); |
||
1672 | } |
||
1673 | |||
1674 | // Compute the time zone offset and DST offset. There are two potential |
||
1675 | // ambiguities here. We'll assume a 2:00 am (wall time) switchover time |
||
1676 | // for discussion purposes here. |
||
1677 | // 1. The transition into DST. Here, a designated time of 2:00 am - 2:59 am |
||
1678 | // can be in standard or in DST depending. However, 2:00 am is an invalid |
||
1679 | // representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST). |
||
1680 | // We assume standard time. |
||
1681 | // 2. The transition out of DST. Here, a designated time of 1:00 am - 1:59 am |
||
1682 | // can be in standard or DST. Both are valid representations (the rep |
||
1683 | // jumps from 1:59:59 DST to 1:00:00 Std). |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
46% 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. ![]() |
|||
1684 | // Again, we assume standard time. |
||
1685 | // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET |
||
1686 | // or DST_OFFSET fields; then we use those fields. |
||
1687 | if ($this->fStamp[DateDefinitions::ZONE_OFFSET] >= (self::kMinimumUserStamp) || |
||
1688 | $this->fStamp[DateDefinitions::DST_OFFSET] >= (self::kMinimumUserStamp)) { |
||
1689 | $millisInDay -= $this->internalGet(DateDefinitions::ZONE_OFFSET) + $this->internalGet(DateDefinitions::DST_OFFSET); |
||
1690 | } else { |
||
1691 | $millisInDay -= $this->computeZoneOffset($millis, $millisInDay); |
||
1692 | } |
||
1693 | |||
1694 | $this->internalSetTime($millis + $millisInDay); |
||
1695 | } |
||
1696 | |||
1697 | /** |
||
1698 | * Converts GMT as milliseconds to time field values. This allows you to sync |
||
1699 | * up the time field values with a new time that is set for the calendar. |
||
1700 | * This method does NOT recompute the time first; to recompute the time, then |
||
1701 | * the fields, use the method complete(). |
||
1702 | * |
||
1703 | * @author Dominik del Bondio <[email protected]> |
||
1704 | * @author The ICU Project |
||
1705 | * @since 0.11.0 |
||
1706 | */ |
||
1707 | protected function computeFields() |
||
1708 | { |
||
1709 | // Compute local wall millis |
||
1710 | $localMillis = $this->internalGetTime(); |
||
1711 | |||
1712 | $rawOffset = $dstOffset = 0; |
||
1713 | $this->getTimeZone()->getOffsetRef($localMillis, false, $rawOffset, $dstOffset); |
||
1714 | $localMillis += $rawOffset; |
||
1715 | |||
1716 | // Mark fields as set. Do this before calling handleComputeFields(). |
||
1717 | $mask = //fInternalSetMask; |
||
1718 | (1 << DateDefinitions::ERA) | |
||
1719 | (1 << DateDefinitions::YEAR) | |
||
1720 | (1 << DateDefinitions::MONTH) | |
||
1721 | (1 << DateDefinitions::DAY_OF_MONTH) | // = UCAL_DATE |
||
1722 | (1 << DateDefinitions::DAY_OF_YEAR) | |
||
1723 | (1 << DateDefinitions::EXTENDED_YEAR); |
||
1724 | |||
1725 | for ($i = 0; $i < DateDefinitions::FIELD_COUNT; ++$i) { |
||
1726 | if (($mask & 1) == 0) { |
||
1727 | $this->fStamp[$i] = self::kInternallySet; |
||
1728 | $this->fIsSet[$i] = true; // Remove later |
||
0 ignored issues
–
show
The property
Agavi\Date\Calendar::$fIsSet has been deprecated with message: ICU 2.8 use (fStamp[n]!=kUnset)
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
|||
1729 | } else { |
||
1730 | $this->fStamp[$i] = self::kUnset; |
||
1731 | $this->fIsSet[$i] = false; // Remove later |
||
0 ignored issues
–
show
The property
Agavi\Date\Calendar::$fIsSet has been deprecated with message: ICU 2.8 use (fStamp[n]!=kUnset)
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
|||
1732 | } |
||
1733 | $mask >>= 1; |
||
1734 | } |
||
1735 | |||
1736 | // We used to check for and correct extreme millis values (near |
||
1737 | // Long.MIN_VALUE or Long.MAX_VALUE) here. Such values would cause |
||
1738 | // overflows from positive to negative (or vice versa) and had to |
||
1739 | // be manually tweaked. We no longer need to do this because we |
||
1740 | // have limited the range of supported dates to those that have a |
||
1741 | // Julian day that fits into an int. This allows us to implement a |
||
1742 | // JULIAN_DAY field and also removes some inelegant code. - Liu |
||
1743 | // 11/6/00 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% 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. ![]() |
|||
1744 | |||
1745 | $days = floor($localMillis / DateDefinitions::MILLIS_PER_DAY); |
||
1746 | |||
1747 | $this->internalSet(DateDefinitions::JULIAN_DAY, $days + DateDefinitions::EPOCH_START_AS_JULIAN_DAY); |
||
1748 | |||
1749 | // In some cases we will have to call this method again below to |
||
1750 | // adjust for DST pushing us into the next Julian day. |
||
1751 | $this->computeGregorianAndDOWFields($this->fFields[DateDefinitions::JULIAN_DAY]); |
||
1752 | |||
1753 | $millisInDay = (int) ($localMillis - ($days * DateDefinitions::MILLIS_PER_DAY)); |
||
1754 | if ($millisInDay < 0) { |
||
1755 | $millisInDay += (int) DateDefinitions::MILLIS_PER_DAY; |
||
1756 | } |
||
1757 | |||
1758 | // Adjust our millisInDay for DST. dstOffset will be zero if DST |
||
1759 | // is not in effect at this time of year, or if our zone does not |
||
1760 | // use DST. |
||
1761 | $millisInDay += $dstOffset; |
||
1762 | |||
1763 | // If DST has pushed us into the next day, we must call |
||
1764 | // computeGregorianAndDOWFields() again. This happens in DST between |
||
1765 | // 12:00 am and 1:00 am every day. The first call to |
||
1766 | // computeGregorianAndDOWFields() will give the wrong day, since the |
||
1767 | // Standard time is in the previous day. |
||
1768 | if ($millisInDay >= (int) DateDefinitions::MILLIS_PER_DAY) { |
||
1769 | $millisInDay -= (int) DateDefinitions::MILLIS_PER_DAY; // ASSUME dstOffset < 24:00 |
||
1770 | |||
1771 | // We don't worry about overflow of JULIAN_DAY because the |
||
1772 | // allowable range of JULIAN_DAY has slop at the ends (that is, |
||
1773 | // the max is less that 0x7FFFFFFF and the min is greater than |
||
1774 | // -0x80000000). |
||
1775 | $this->computeGregorianAndDOWFields(++$this->fFields[DateDefinitions::JULIAN_DAY]); |
||
1776 | } |
||
1777 | |||
1778 | // Call framework method to have subclass compute its fields. |
||
1779 | // These must include, at a minimum, MONTH, DAY_OF_MONTH, |
||
1780 | // EXTENDED_YEAR, YEAR, DAY_OF_YEAR. This method will call internalSet(), |
||
1781 | // which will update stamp[]. |
||
1782 | $this->handleComputeFields($this->fFields[DateDefinitions::JULIAN_DAY]); |
||
1783 | |||
1784 | // Compute week-related fields, based on the subclass-computed |
||
1785 | // fields computed by handleComputeFields(). |
||
1786 | $this->computeWeekFields(); |
||
1787 | |||
1788 | // Compute time-related fields. These are independent of the date and |
||
1789 | // of the subclass algorithm. They depend only on the local zone |
||
1790 | // wall milliseconds in day. |
||
1791 | $this->fFields[DateDefinitions::MILLISECONDS_IN_DAY] = $millisInDay; |
||
1792 | $this->fFields[DateDefinitions::MILLISECOND] = $millisInDay % 1000; |
||
1793 | $millisInDay /= 1000; |
||
1794 | $this->fFields[DateDefinitions::SECOND] = $millisInDay % 60; |
||
1795 | $millisInDay /= 60; |
||
1796 | $this->fFields[DateDefinitions::MINUTE] = $millisInDay % 60; |
||
1797 | $millisInDay /= 60; |
||
1798 | $this->fFields[DateDefinitions::HOUR_OF_DAY] = (int) $millisInDay; |
||
1799 | $this->fFields[DateDefinitions::AM_PM] = (int) ($millisInDay / 12); // Assume AM == 0 |
||
1800 | $this->fFields[DateDefinitions::HOUR] = $millisInDay % 12; |
||
1801 | $this->fFields[DateDefinitions::ZONE_OFFSET] = $rawOffset; |
||
1802 | $this->fFields[DateDefinitions::DST_OFFSET] = $dstOffset; |
||
1803 | } |
||
1804 | |||
1805 | /** |
||
1806 | * Gets this Calendar's current time as a long. |
||
1807 | * |
||
1808 | * @return double the current time as UTC milliseconds from the epoch. |
||
1809 | * |
||
1810 | * @author Dominik del Bondio <[email protected]> |
||
1811 | * @author The ICU Project |
||
1812 | * @since 0.11.0 |
||
1813 | */ |
||
1814 | protected function getTimeInMillis() |
||
1815 | { |
||
1816 | if (!$this->fIsTimeSet) { |
||
1817 | $this->updateTime(); |
||
1818 | } |
||
1819 | |||
1820 | return $this->fTime; |
||
1821 | } |
||
1822 | |||
1823 | /** |
||
1824 | * Sets this Calendar's current time from the given long value. |
||
1825 | * |
||
1826 | * @param double $millis the new time in UTC milliseconds from the epoch. |
||
1827 | * |
||
1828 | * @author Dominik del Bondio <[email protected]> |
||
1829 | * @author The ICU Project |
||
1830 | * @since 0.11.0 |
||
1831 | */ |
||
1832 | protected function setTimeInMillis($millis) |
||
1833 | { |
||
1834 | $millis = (float) $millis; |
||
1835 | |||
1836 | if ($millis > self::MAX_MILLIS) { |
||
1837 | $millis = self::MAX_MILLIS; |
||
1838 | } elseif ($millis < self::MIN_MILLIS) { |
||
1839 | $millis = self::MIN_MILLIS; |
||
1840 | } |
||
1841 | |||
1842 | $this->fTime = $millis; |
||
0 ignored issues
–
show
It seems like
$millis can also be of type integer . However, the property $fTime is declared as type double . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||
1843 | $this->fAreFieldsInSync = $this->fAreAllFieldsSet = false; |
||
1844 | $this->fIsTimeSet = $this->fAreFieldsVirtuallySet = true; |
||
1845 | } |
||
1846 | |||
1847 | /** |
||
1848 | * Recomputes the current time from currently set fields, and then fills in |
||
1849 | * any unset fields in the time field list. |
||
1850 | * |
||
1851 | * @author Dominik del Bondio <[email protected]> |
||
1852 | * @author The ICU Project |
||
1853 | * @since 0.11.0 |
||
1854 | */ |
||
1855 | protected function complete() |
||
1856 | { |
||
1857 | if (!$this->fIsTimeSet) { |
||
1858 | $this->updateTime(); |
||
1859 | } |
||
1860 | |||
1861 | if (!$this->fAreFieldsInSync) { |
||
1862 | $this->computeFields(); // fills in unset fields |
||
1863 | |||
1864 | $this->fAreFieldsInSync = true; |
||
1865 | $this->fAreAllFieldsSet = true; |
||
1866 | } |
||
1867 | } |
||
1868 | |||
1869 | /** |
||
1870 | * Gets the value for a given time field. Subclasses can use this function to |
||
1871 | * get field values without forcing recomputation of time. If the field's |
||
1872 | * stamp is UNSET, the defaultValue is used. |
||
1873 | * |
||
1874 | * @param int $field The given time field. |
||
1875 | * @param int $defaultValue a default value used if the field is unset. |
||
1876 | * @return int The value for the given time field. |
||
1877 | * |
||
1878 | * @author Dominik del Bondio <[email protected]> |
||
1879 | * @author The ICU Project |
||
1880 | * @since 0.11.0 |
||
1881 | */ |
||
1882 | protected function internalGet($field, $defaultValue = null) |
||
1883 | { |
||
1884 | return $this->fStamp[$field] > self::kUnset ? $this->fFields[$field] : $defaultValue; |
||
1885 | } |
||
1886 | |||
1887 | /** |
||
1888 | * Sets the value for a given time field. This is a fast internal method for |
||
1889 | * subclasses. It does not affect the fAreFieldsInSync, isTimeSet, or |
||
1890 | * areAllFieldsSet flags. |
||
1891 | * |
||
1892 | * @param int $field The given time field. |
||
1893 | * @param int $value The value for the given time field. |
||
1894 | * |
||
1895 | * @author Dominik del Bondio <[email protected]> |
||
1896 | * @author The ICU Project |
||
1897 | * @since 0.11.0 |
||
1898 | */ |
||
1899 | protected function internalSet($field, $value) |
||
1900 | { |
||
1901 | $this->fFields[$field] = $value; |
||
1902 | $this->fStamp[$field] = self::kInternallySet; |
||
1903 | $this->fIsSet[$field] = true; // Remove later |
||
0 ignored issues
–
show
The property
Agavi\Date\Calendar::$fIsSet has been deprecated with message: ICU 2.8 use (fStamp[n]!=kUnset)
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
|||
1904 | } |
||
1905 | |||
1906 | /** |
||
1907 | * Prepare this calendar for computing the actual minimum or maximum. |
||
1908 | * This method modifies this calendar's fields; it is called on a |
||
1909 | * temporary calendar. |
||
1910 | * |
||
1911 | * @param int $field The given time field |
||
1912 | * @param bool $isMinimum |
||
1913 | * |
||
1914 | * @author Dominik del Bondio <[email protected]> |
||
1915 | * @author The ICU Project |
||
1916 | * @since 0.11.0 |
||
1917 | */ |
||
1918 | protected function prepareGetActual($field, $isMinimum) |
||
1919 | { |
||
1920 | $this->set(DateDefinitions::MILLISECONDS_IN_DAY, 0); |
||
1921 | |||
1922 | switch ($field) { |
||
1923 | case DateDefinitions::YEAR: |
||
1924 | case DateDefinitions::YEAR_WOY: |
||
1925 | case DateDefinitions::EXTENDED_YEAR: |
||
1926 | $this->set(DateDefinitions::DAY_OF_YEAR, $this->getGreatestMinimum(DateDefinitions::DAY_OF_YEAR)); |
||
1927 | break; |
||
1928 | |||
1929 | case DateDefinitions::MONTH: |
||
1930 | $this->set(DateDefinitions::DATE, $this->getGreatestMinimum(DateDefinitions::DATE)); |
||
1931 | break; |
||
1932 | |||
1933 | case DateDefinitions::DAY_OF_WEEK_IN_MONTH: |
||
1934 | // For dowim, the maximum occurs for the DOW of the first of the |
||
1935 | // month. |
||
1936 | $this->set(DateDefinitions::DATE, 1); |
||
1937 | $this->set(DateDefinitions::DAY_OF_WEEK, $this->get(DateDefinitions::DAY_OF_WEEK)); // Make this user set |
||
1938 | break; |
||
1939 | |||
1940 | case DateDefinitions::WEEK_OF_MONTH: |
||
1941 | case DateDefinitions::WEEK_OF_YEAR: |
||
1942 | // If we're counting weeks, set the day of the week to either the |
||
1943 | // first or last localized DOW. We know the last week of a month |
||
1944 | // or year will contain the first day of the week, and that the |
||
1945 | // first week will contain the last DOW. |
||
1946 | $dow = $this->fFirstDayOfWeek; |
||
1947 | if ($isMinimum) { |
||
1948 | $dow = ($dow + 6) % 7; // set to last DOW |
||
1949 | if ($dow < DateDefinitions::SUNDAY) { |
||
1950 | $dow += 7; |
||
1951 | } |
||
1952 | } |
||
1953 | |||
1954 | $this->set(DateDefinitions::DAY_OF_WEEK, $dow); |
||
1955 | break; |
||
1956 | default: |
||
1957 | ; |
||
1958 | } |
||
1959 | |||
1960 | // Do this last to give it the newest time stamp |
||
1961 | $this->set($field, $this->getGreatestMinimum($field)); |
||
1962 | } |
||
1963 | |||
1964 | /** |
||
1965 | * Subclass API for defining limits of different types. |
||
1966 | * Subclasses must implement this method to return limits for the |
||
1967 | * following fields: |
||
1968 | * |
||
1969 | * <pre>DateDefinitions::ERA |
||
1970 | * DateDefinitions::YEAR |
||
1971 | * DateDefinitions::MONTH |
||
1972 | * DateDefinitions::WEEK_OF_YEAR |
||
1973 | * DateDefinitions::WEEK_OF_MONTH |
||
1974 | * DateDefinitions::DATE |
||
1975 | * DateDefinitions::DAY_OF_YEAR |
||
1976 | * DateDefinitions::DAY_OF_WEEK_IN_MONTH |
||
1977 | * DateDefinitions::YEAR_WOY |
||
1978 | * DateDefinitions::EXTENDED_YEAR</pre> |
||
1979 | * |
||
1980 | * @param int $field one of the above field numbers |
||
1981 | * @param int $limitType one of <code>self::LIMIT_MINIMUM</code>, |
||
1982 | * <code>self::LIMIT_GREATEST_MINIMUM</code>, |
||
1983 | * <code>self::LIMIT_LEAST_MAXIMUM</code>, |
||
1984 | * or <code>self::LIMIT_MAXIMUM</code> |
||
1985 | * |
||
1986 | * @return int |
||
1987 | * |
||
1988 | * @author Dominik del Bondio <[email protected]> |
||
1989 | * @author The ICU Project |
||
1990 | * @since 0.11.0 |
||
1991 | */ |
||
1992 | abstract protected function handleGetLimit($field, $limitType); |
||
1993 | |||
1994 | /** |
||
1995 | * Return a limit for a field. |
||
1996 | * |
||
1997 | * @param int $field the field |
||
1998 | * @param int $limitType the type specifier for the limit |
||
1999 | * |
||
2000 | * @return int |
||
2001 | * |
||
2002 | * @author Dominik del Bondio <[email protected]> |
||
2003 | * @author The ICU Project |
||
2004 | * @since 0.11.0 |
||
2005 | */ |
||
2006 | protected function getLimit($field, $limitType) |
||
2007 | { |
||
2008 | switch ($field) { |
||
2009 | case DateDefinitions::DAY_OF_WEEK: |
||
2010 | case DateDefinitions::AM_PM: |
||
2011 | case DateDefinitions::HOUR: |
||
2012 | case DateDefinitions::HOUR_OF_DAY: |
||
2013 | case DateDefinitions::MINUTE: |
||
2014 | case DateDefinitions::SECOND: |
||
2015 | case DateDefinitions::MILLISECOND: |
||
2016 | case DateDefinitions::ZONE_OFFSET: |
||
2017 | case DateDefinitions::DST_OFFSET: |
||
2018 | case DateDefinitions::DOW_LOCAL: |
||
2019 | case DateDefinitions::JULIAN_DAY: |
||
2020 | case DateDefinitions::MILLISECONDS_IN_DAY: |
||
2021 | return self::$kCalendarLimits[$field][$limitType]; |
||
2022 | default: |
||
2023 | return $this->handleGetLimit($field, $limitType); |
||
2024 | } |
||
2025 | } |
||
2026 | |||
2027 | /** |
||
2028 | * Return the Julian day number of day before the first day of the |
||
2029 | * given month in the given extended year. Subclasses should override |
||
2030 | * this method to implement their calendar system. |
||
2031 | * |
||
2032 | * @param int $eyear the extended year |
||
2033 | * @param int $month the zero-based month, or 0 if useMonth is false |
||
2034 | * @param bool $useMonth if false, compute the day before the first day of |
||
2035 | * the given year, otherwise, compute the day before the |
||
2036 | * first day of the given month |
||
2037 | * |
||
2038 | * @return int the Julian day number of the day before the first |
||
2039 | * day of the given month and year |
||
2040 | * |
||
2041 | * @author Dominik del Bondio <[email protected]> |
||
2042 | * @author The ICU Project |
||
2043 | * @since 0.11.0 |
||
2044 | */ |
||
2045 | abstract protected function handleComputeMonthStart($eyear, $month, $useMonth); |
||
2046 | |||
2047 | /** |
||
2048 | * Return the number of days in the given month of the given extended |
||
2049 | * year of this calendar system. Subclasses should override this |
||
2050 | * method if they can provide a more correct or more efficient |
||
2051 | * implementation than the default implementation in Calendar. |
||
2052 | * |
||
2053 | * @author Dominik del Bondio <[email protected]> |
||
2054 | * @author The ICU Project |
||
2055 | * @since 0.11.0 |
||
2056 | */ |
||
2057 | protected function handleGetMonthLength($extendedYear, $month) |
||
2058 | { |
||
2059 | return $this->handleComputeMonthStart($extendedYear, $month + 1, true) - |
||
2060 | $this->handleComputeMonthStart($extendedYear, $month, true); |
||
2061 | } |
||
2062 | |||
2063 | /** |
||
2064 | * Return the number of days in the given extended year of this |
||
2065 | * calendar system. Subclasses should override this method if they can |
||
2066 | * provide a more correct or more efficient implementation than the |
||
2067 | * default implementation in Calendar. |
||
2068 | * |
||
2069 | * @author Dominik del Bondio <[email protected]> |
||
2070 | * @author The ICU Project |
||
2071 | * @since 0.11.0 |
||
2072 | */ |
||
2073 | protected function handleGetYearLength($eyear) |
||
2074 | { |
||
2075 | return $this->handleComputeMonthStart($eyear + 1, 0, false) - |
||
2076 | $this->handleComputeMonthStart($eyear, 0, false); |
||
2077 | } |
||
2078 | |||
2079 | /** |
||
2080 | * Return the extended year defined by the current fields. This will |
||
2081 | * use the EXTENDED_YEAR field or the YEAR and supra-year fields |
||
2082 | * (such as ERA) specific to the calendar system, depending on which set |
||
2083 | * of fields is newer. |
||
2084 | * |
||
2085 | * @return int the extended year |
||
2086 | * |
||
2087 | * @author Dominik del Bondio <[email protected]> |
||
2088 | * @author The ICU Project |
||
2089 | * @since 0.11.0 |
||
2090 | */ |
||
2091 | abstract protected function handleGetExtendedYear(); |
||
2092 | |||
2093 | /** |
||
2094 | * Subclasses may override this. This method calls |
||
2095 | * handleGetMonthLength() to obtain the calendar-specific month |
||
2096 | * length. |
||
2097 | * |
||
2098 | * @param string $bestField which field to use to calculate the date |
||
2099 | * |
||
2100 | * @return int julian day specified by calendar fields. |
||
2101 | * |
||
2102 | * @author Dominik del Bondio <[email protected]> |
||
2103 | * @author The ICU Project |
||
2104 | * @since 0.11.0 |
||
2105 | */ |
||
2106 | protected function handleComputeJulianDay($bestField) |
||
2107 | { |
||
2108 | $useMonth = ($bestField == DateDefinitions::DAY_OF_MONTH || |
||
2109 | $bestField == DateDefinitions::WEEK_OF_MONTH || |
||
2110 | $bestField == DateDefinitions::DAY_OF_WEEK_IN_MONTH); |
||
2111 | $year = 0; |
||
0 ignored issues
–
show
$year 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 ![]() |
|||
2112 | |||
2113 | if ($bestField == DateDefinitions::WEEK_OF_YEAR) { |
||
2114 | $year = $this->internalGet(DateDefinitions::YEAR_WOY, $this->handleGetExtendedYear()); |
||
2115 | $this->internalSet(DateDefinitions::EXTENDED_YEAR, $year); |
||
2116 | } else { |
||
2117 | $year = $this->handleGetExtendedYear(); |
||
2118 | $this->internalSet(DateDefinitions::EXTENDED_YEAR, $year); |
||
2119 | } |
||
2120 | |||
2121 | // Get the Julian day of the day BEFORE the start of this year. |
||
2122 | // If useMonth is true, get the day before the start of the month. |
||
2123 | |||
2124 | // give calendar subclass a chance to have a default 'first' month |
||
2125 | $month = 0; |
||
0 ignored issues
–
show
$month 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 ![]() |
|||
2126 | |||
2127 | if ($this->_isSet(DateDefinitions::MONTH)) { |
||
2128 | $month = $this->internalGet(DateDefinitions::MONTH); |
||
2129 | } else { |
||
2130 | $month = $this->getDefaultMonthInYear(); |
||
2131 | } |
||
2132 | |||
2133 | $julianDay = $this->handleComputeMonthStart($year, $useMonth ? $month : 0, $useMonth); |
||
2134 | |||
2135 | if ($bestField == DateDefinitions::DAY_OF_MONTH) { |
||
2136 | // give calendar subclass a chance to have a default 'first' dom |
||
2137 | $dayOfMonth = 0; |
||
0 ignored issues
–
show
$dayOfMonth 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 ![]() |
|||
2138 | if ($this->_isSet(DateDefinitions::DAY_OF_MONTH)) { |
||
2139 | $dayOfMonth = $this->internalGet(DateDefinitions::DAY_OF_MONTH, 1); |
||
2140 | } else { |
||
2141 | $dayOfMonth = $this->getDefaultDayInMonth($month); |
||
2142 | } |
||
2143 | |||
2144 | return $julianDay + $dayOfMonth; |
||
2145 | } |
||
2146 | |||
2147 | if ($bestField == DateDefinitions::DAY_OF_YEAR) { |
||
2148 | return $julianDay + $this->internalGet(DateDefinitions::DAY_OF_YEAR); |
||
2149 | } |
||
2150 | |||
2151 | $firstDayOfWeek = $this->getFirstDayOfWeek(); // Localized fdw |
||
2152 | |||
2153 | // At this point julianDay is the 0-based day BEFORE the first day of |
||
2154 | // January 1, year 1 of the given calendar. If julianDay == 0, it |
||
2155 | // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian |
||
2156 | // or Gregorian). (or it is before the month we are in, if useMonth is True) |
||
2157 | |||
2158 | // At this point we need to process the WEEK_OF_MONTH or |
||
2159 | // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH. |
||
2160 | // First, perform initial shared computations. These locate the |
||
2161 | // first week of the period. |
||
2162 | |||
2163 | // Get the 0-based localized DOW of day one of the month or year. |
||
2164 | // Valid range 0..6. |
||
2165 | $first = $this->julianDayToDayOfWeek($julianDay + 1) - $firstDayOfWeek; |
||
2166 | if ($first < 0) { |
||
2167 | $first += 7; |
||
2168 | } |
||
2169 | |||
2170 | $dowLocal = $this->getLocalDOW(); |
||
2171 | |||
2172 | // Find the first target DOW (dowLocal) in the month or year. |
||
2173 | // Actually, it may be just before the first of the month or year. |
||
2174 | // It will be an integer from -5..7. |
||
2175 | $date = 1 - $first + $dowLocal; |
||
2176 | |||
2177 | if ($bestField == DateDefinitions::DAY_OF_WEEK_IN_MONTH) { |
||
2178 | // Adjust the target DOW to be in the month or year. |
||
2179 | if ($date < 1) { |
||
2180 | $date += 7; |
||
2181 | } |
||
2182 | |||
2183 | // The only trickiness occurs if the day-of-week-in-month is |
||
2184 | // negative. |
||
2185 | $dim = $this->internalGet(DateDefinitions::DAY_OF_WEEK_IN_MONTH, 1); |
||
2186 | if ($dim >= 0) { |
||
2187 | $date += 7 * ($dim - 1); |
||
2188 | } else { |
||
2189 | // Move date to the last of this day-of-week in this month, |
||
2190 | // then back up as needed. If dim==-1, we don't back up at |
||
2191 | // all. If dim==-2, we back up once, etc. Don't back up |
||
2192 | // past the first of the given day-of-week in this month. |
||
2193 | // Note that we handle -2, -3, etc. correctly, even though |
||
2194 | // values < -1 are technically disallowed. |
||
2195 | $m = $this->internalGet(DateDefinitions::MONTH, DateDefinitions::JANUARY); |
||
2196 | $monthLength = $this->handleGetMonthLength($year, $m); |
||
2197 | $date += ((int)(($monthLength - $date) / 7) + $dim + 1) * 7; |
||
2198 | } |
||
2199 | } else { |
||
2200 | if ($bestField == DateDefinitions::WEEK_OF_YEAR) { // ------------------------------------- WOY ------------- |
||
2201 | if (!$this->_isSet(DateDefinitions::YEAR_WOY) || // YWOY not set at all or |
||
2202 | ( |
||
2203 | ($this->resolveFields(self::$kYearPrecedence) != DateDefinitions::YEAR_WOY) // YWOY doesn't have precedence |
||
2204 | && ($this->fStamp[DateDefinitions::YEAR_WOY] != self::kInternallySet) // (excluding where all fields are internally set - then YWOY is used) |
||
2205 | ) |
||
2206 | ) { |
||
2207 | // need to be sure to stay in 'real' year. |
||
2208 | $woy = $this->internalGet($bestField); |
||
2209 | |||
2210 | $nextJulianDay = $this->handleComputeMonthStart($year + 1, 0, false); // jd of day before jan 1 |
||
2211 | $nextFirst = $this->julianDayToDayOfWeek($nextJulianDay + 1) - $firstDayOfWeek; |
||
2212 | |||
2213 | if ($nextFirst < 0) { // 0..6 ldow of Jan 1 |
||
2214 | $nextFirst += 7; |
||
2215 | } |
||
2216 | |||
2217 | if ($woy == 1) { // FIRST WEEK --------------------------------- |
||
2218 | |||
2219 | // nextFirst is now the localized DOW of Jan 1 of y-woy+1 |
||
2220 | View Code Duplication | if (($nextFirst > 0) && // Jan 1 starts on FDOW |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
2221 | (7 - $nextFirst) >= $this->getMinimalDaysInFirstWeek() // or enough days in the week |
||
2222 | ) { |
||
2223 | // Jan 1 of (yearWoy+1) is in yearWoy+1 - recalculate JD to next year |
||
2224 | $julianDay = $nextJulianDay; |
||
2225 | |||
2226 | // recalculate 'first' [0-based local dow of jan 1] |
||
2227 | $first = $this->julianDayToDayOfWeek($julianDay + 1) - $firstDayOfWeek; |
||
2228 | if ($first < 0) { |
||
2229 | $first += 7; |
||
2230 | } |
||
2231 | // recalculate date. |
||
2232 | $date = 1 - $first + $dowLocal; |
||
2233 | } |
||
2234 | } elseif ($woy >= $this->getLeastMaximum($bestField)) { |
||
2235 | // could be in the last week- find out if this JD would overstep |
||
2236 | $testDate = $date; |
||
2237 | if ((7 - $first) < $this->getMinimalDaysInFirstWeek()) { |
||
2238 | $testDate += 7; |
||
2239 | } |
||
2240 | |||
2241 | // Now adjust for the week number. |
||
2242 | $testDate += 7 * ($woy - 1); |
||
2243 | |||
2244 | View Code Duplication | if ($julianDay + $testDate > $nextJulianDay) { // is it past Dec 31? (nextJulianDay is day BEFORE year+1's Jan 1) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
2245 | // Fire up the calculating engines.. retry YWOY = (year-1) |
||
2246 | $julianDay = $this->handleComputeMonthStart($year - 1, 0, false); // jd before Jan 1 of previous year |
||
2247 | $first = $this->julianDayToDayOfWeek($julianDay + 1) - $firstDayOfWeek; // 0 based local dow of first week |
||
2248 | |||
2249 | if ($first < 0) { // 0..6 |
||
2250 | $first += 7; |
||
2251 | } |
||
2252 | $date = 1 - $first + $dowLocal; |
||
2253 | } /* correction needed */ |
||
2254 | } /* leastmaximum */ |
||
2255 | } /* resolvefields(year) != year_woy */ |
||
2256 | } /* bestfield != week_of_year */ |
||
2257 | |||
2258 | // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR) |
||
2259 | // Adjust for minimal days in first week |
||
2260 | if ((7 - $first) < $this->getMinimalDaysInFirstWeek()) { |
||
2261 | $date += 7; |
||
2262 | } |
||
2263 | |||
2264 | // Now adjust for the week number. |
||
2265 | $date += 7 * ($this->internalGet($bestField) - 1); |
||
2266 | } |
||
2267 | |||
2268 | return $julianDay + $date; |
||
2269 | } |
||
2270 | |||
2271 | /** |
||
2272 | * Subclasses must override this to convert from week fields |
||
2273 | * (YEAR_WOY and WEEK_OF_YEAR) to an extended year in the case |
||
2274 | * where YEAR, EXTENDED_YEAR are not set. |
||
2275 | * The Calendar implementation assumes yearWoy is in extended gregorian form |
||
2276 | * |
||
2277 | * @internal |
||
2278 | * |
||
2279 | * @param int $yearWoy |
||
2280 | * @param int $woy |
||
2281 | * |
||
2282 | * @return int the extended year, UCAL_EXTENDED_YEAR |
||
2283 | * |
||
2284 | * @author Dominik del Bondio <[email protected]> |
||
2285 | * @author The ICU Project |
||
2286 | * @since 0.11.0 |
||
2287 | */ |
||
2288 | protected function handleGetExtendedYearFromWeekFields($yearWoy, $woy) |
||
2289 | { |
||
2290 | // We have UCAL_YEAR_WOY and UCAL_WEEK_OF_YEAR - from those, determine |
||
2291 | // what year we fall in, so that other code can set it properly. |
||
2292 | // (code borrowed from computeWeekFields and handleComputeJulianDay) |
||
2293 | //return yearWoy; |
||
2294 | |||
2295 | // First, we need a reliable DOW. |
||
2296 | $bestField = $this->resolveFields(self::$kDatePrecedence); // !! Note: if subclasses have a different table, they should override handleGetExtendedYearFromWeekFields |
||
2297 | |||
2298 | // Now, a local DOW |
||
2299 | $dowLocal = $this->getLocalDOW(); // 0..6 |
||
2300 | $firstDayOfWeek = $this->getFirstDayOfWeek(); // Localized fdw |
||
2301 | $jan1Start = $this->handleComputeMonthStart($yearWoy, 0, false); |
||
2302 | $nextJan1Start = $this->handleComputeMonthStart($yearWoy + 1, 0, false); // next year's Jan1 start |
||
2303 | |||
2304 | // At this point julianDay is the 0-based day BEFORE the first day of |
||
2305 | // January 1, year 1 of the given calendar. If julianDay == 0, it |
||
2306 | // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian |
||
2307 | // or Gregorian). (or it is before the month we are in, if useMonth is True) |
||
2308 | |||
2309 | // At this point we need to process the WEEK_OF_MONTH or |
||
2310 | // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH. |
||
2311 | // First, perform initial shared computations. These locate the |
||
2312 | // first week of the period. |
||
2313 | |||
2314 | // Get the 0-based localized DOW of day one of the month or year. |
||
2315 | // Valid range 0..6. |
||
2316 | $first = $this->julianDayToDayOfWeek($jan1Start + 1) - $firstDayOfWeek; |
||
2317 | if ($first < 0) { |
||
2318 | $first += 7; |
||
2319 | } |
||
2320 | $nextFirst = $this->julianDayToDayOfWeek($nextJan1Start + 1) - $firstDayOfWeek; |
||
2321 | if ($nextFirst < 0) { |
||
2322 | $nextFirst += 7; |
||
2323 | } |
||
2324 | |||
2325 | $minDays = $this->getMinimalDaysInFirstWeek(); |
||
2326 | $jan1InPrevYear = false; // January 1st in the year of WOY is the 1st week? (i.e. first week is < minimal ) |
||
2327 | //UBool nextJan1InPrevYear = false; // January 1st of Year of WOY + 1 is in the first week? |
||
2328 | |||
2329 | if ((7 - $first) < $minDays) { |
||
2330 | $jan1InPrevYear = true; |
||
2331 | } |
||
2332 | |||
2333 | // if((7 - nextFirst) < minDays) { |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
42% 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. ![]() |
|||
2334 | // nextJan1InPrevYear = true; |
||
2335 | // } |
||
2336 | |||
2337 | switch ($bestField) { |
||
2338 | case DateDefinitions::WEEK_OF_YEAR: |
||
2339 | if ($woy == 1) { |
||
2340 | if ($jan1InPrevYear == true) { |
||
0 ignored issues
–
show
|
|||
2341 | // the first week of January is in the previous year |
||
2342 | // therefore WOY1 is always solidly within yearWoy |
||
2343 | return $yearWoy; |
||
2344 | } else { |
||
2345 | // First WOY is split between two years |
||
2346 | if ($dowLocal < $first) { // we are prior to Jan 1 |
||
2347 | return $yearWoy - 1; // previous year |
||
2348 | } else { |
||
2349 | return $yearWoy; // in this year |
||
2350 | } |
||
2351 | } |
||
2352 | } elseif ($woy >= $this->getLeastMaximum($bestField)) { |
||
2353 | // we _might_ be in the last week.. |
||
2354 | $jd = // Calculate JD of our target day: |
||
2355 | $jan1Start + // JD of Jan 1 |
||
2356 | (7 - $first) + // days in the first week (Jan 1.. ) |
||
2357 | ($woy - 1) * 7 + // add the weeks of the year |
||
2358 | $dowLocal; // the local dow (0..6) of last week |
||
2359 | if ($jan1InPrevYear == false) { |
||
0 ignored issues
–
show
|
|||
2360 | $jd -= 7; // woy already includes Jan 1's week. |
||
2361 | } |
||
2362 | |||
2363 | if (($jd + 1) >= $nextJan1Start) { |
||
2364 | // we are in week 52 or 53 etc. - actual year is yearWoy+1 |
||
2365 | return $yearWoy + 1; |
||
2366 | } else { |
||
2367 | // still in yearWoy; |
||
2368 | return $yearWoy; |
||
2369 | } |
||
2370 | } else { |
||
2371 | // we're not possibly in the last week -must be ywoy |
||
2372 | return $yearWoy; |
||
2373 | } |
||
2374 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
2375 | |||
2376 | case DateDefinitions::DATE: |
||
2377 | if (($this->internalGet(DateDefinitions::MONTH)==0) && |
||
2378 | ($woy >= $this->getLeastMaximum(DateDefinitions::WEEK_OF_YEAR))) { |
||
2379 | return $yearWoy + 1; // month 0, late woy = in the next year |
||
2380 | } elseif ($woy == 1) { |
||
2381 | //if(nextJan1InPrevYear) { |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
67% 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. ![]() |
|||
2382 | if ($this->internalGet(DateDefinitions::MONTH)==0) { |
||
2383 | return $yearWoy; |
||
2384 | } else { |
||
2385 | return $yearWoy - 1; |
||
2386 | } |
||
2387 | //} |
||
2388 | } |
||
2389 | |||
2390 | //(internalGet(UCAL_DATE) <= (7-first)) /* && in minDow */ ) { |
||
2391 | //within 1st week and in this month.. |
||
2392 | //return yearWoy+1; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% 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. ![]() |
|||
2393 | return $yearWoy; |
||
2394 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
2395 | |||
2396 | default: // assume the year is appropriate |
||
2397 | return $yearWoy; |
||
2398 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
2399 | } |
||
2400 | } |
||
2401 | |||
2402 | /** |
||
2403 | * Compute the Julian day from fields. Will determine whether to use |
||
2404 | * the JULIAN_DAY field directly, or other fields. |
||
2405 | * |
||
2406 | * @return int the julian day |
||
2407 | * |
||
2408 | * @author Dominik del Bondio <[email protected]> |
||
2409 | * @author The ICU Project |
||
2410 | * @since 0.11.0 |
||
2411 | */ |
||
2412 | protected function computeJulianDay() |
||
2413 | { |
||
2414 | // We want to see if any of the date fields is newer than the |
||
2415 | // JULIAN_DAY. If not, then we use JULIAN_DAY. If so, then we do |
||
2416 | // the normal resolution. We only use JULIAN_DAY if it has been |
||
2417 | // set by the user. This makes it possible for the caller to set |
||
2418 | // the calendar to a time and call clear(MONTH) to reset the MONTH |
||
2419 | // to January. This is legacy behavior. Without this, |
||
2420 | // clear(MONTH) has no effect, since the internally set JULIAN_DAY |
||
2421 | // is used. |
||
2422 | if ($this->fStamp[DateDefinitions::JULIAN_DAY] >= (int)self::kMinimumUserStamp) { |
||
2423 | $bestStamp = $this->newestStamp(DateDefinitions::ERA, DateDefinitions::DAY_OF_WEEK_IN_MONTH, self::kUnset); |
||
2424 | $bestStamp = $this->newestStamp(DateDefinitions::YEAR_WOY, DateDefinitions::EXTENDED_YEAR, $bestStamp); |
||
2425 | if ($bestStamp <= $this->fStamp[DateDefinitions::JULIAN_DAY]) { |
||
2426 | return $this->internalGet(DateDefinitions::JULIAN_DAY); |
||
2427 | } |
||
2428 | } |
||
2429 | |||
2430 | $bestField = $this->resolveFields($this->getFieldResolutionTable()); |
||
2431 | if ($bestField == DateDefinitions::FIELD_COUNT) { |
||
2432 | $bestField = DateDefinitions::DAY_OF_MONTH; |
||
2433 | } |
||
2434 | |||
2435 | return $this->handleComputeJulianDay($bestField); |
||
2436 | } |
||
2437 | |||
2438 | /** |
||
2439 | * Compute the milliseconds in the day from the fields. This is a |
||
2440 | * value from 0 to 23:59:59.999 inclusive, unless fields are out of |
||
2441 | * range, in which case it can be an arbitrary value. This value |
||
2442 | * reflects local zone wall time. |
||
2443 | * |
||
2444 | * @return int The milliseconds in the day |
||
2445 | * |
||
2446 | * @author Dominik del Bondio <[email protected]> |
||
2447 | * @author The ICU Project |
||
2448 | * @since 0.11.0 |
||
2449 | */ |
||
2450 | protected function computeMillisInDay() |
||
2451 | { |
||
2452 | // Do the time portion of the conversion. |
||
2453 | |||
2454 | $millisInDay = 0; |
||
2455 | |||
2456 | // Find the best set of fields specifying the time of day. There |
||
2457 | // are only two possibilities here; the HOUR_OF_DAY or the |
||
2458 | // AM_PM and the HOUR. |
||
2459 | $hourOfDayStamp = $this->fStamp[DateDefinitions::HOUR_OF_DAY]; |
||
2460 | $hourStamp = ($this->fStamp[DateDefinitions::HOUR] > $this->fStamp[DateDefinitions::AM_PM]) ? $this->fStamp[DateDefinitions::HOUR] : $this->fStamp[DateDefinitions::AM_PM]; |
||
2461 | $bestStamp = ($hourStamp > $hourOfDayStamp) ? $hourStamp : $hourOfDayStamp; |
||
2462 | |||
2463 | // Hours |
||
2464 | if ($bestStamp != self::kUnset) { |
||
2465 | if ($bestStamp == $hourOfDayStamp) { |
||
2466 | // Don't normalize here; let overflow bump into the next period. |
||
2467 | // This is consistent with how we handle other fields. |
||
2468 | $millisInDay += $this->internalGet(DateDefinitions::HOUR_OF_DAY); |
||
2469 | } else { |
||
2470 | // Don't normalize here; let overflow bump into the next period. |
||
2471 | // This is consistent with how we handle other fields. |
||
2472 | $millisInDay += $this->internalGet(DateDefinitions::HOUR); |
||
2473 | $millisInDay += 12 * $this->internalGet(DateDefinitions::AM_PM); // Default works for unset AM_PM |
||
2474 | } |
||
2475 | } |
||
2476 | |||
2477 | // We use the fact that unset == 0; we start with millisInDay |
||
2478 | // == HOUR_OF_DAY. |
||
2479 | $millisInDay *= 60; |
||
2480 | $millisInDay += $this->internalGet(DateDefinitions::MINUTE); // now have minutes |
||
2481 | $millisInDay *= 60; |
||
2482 | $millisInDay += $this->internalGet(DateDefinitions::SECOND); // now have seconds |
||
2483 | $millisInDay *= 1000; |
||
2484 | $millisInDay += $this->internalGet(DateDefinitions::MILLISECOND); // now have millis |
||
2485 | |||
2486 | return $millisInDay; |
||
2487 | } |
||
2488 | |||
2489 | /** |
||
2490 | * This method can assume EXTENDED_YEAR has been set. |
||
2491 | * |
||
2492 | * @param double $millis milliseconds of the date fields |
||
2493 | * @param int $millisInDay milliseconds of the time fields; may be out or range. |
||
2494 | * |
||
2495 | * @return int |
||
2496 | * |
||
2497 | * @author Dominik del Bondio <[email protected]> |
||
2498 | * @author The ICU Project |
||
2499 | * @since 0.11.0 |
||
2500 | */ |
||
2501 | protected function computeZoneOffset($millis, $millisInDay) |
||
2502 | { |
||
2503 | $rawOffset = $dstOffset = 0; |
||
2504 | $this->getTimeZone()->getOffsetRef($millis + $millisInDay, true, $rawOffset, $dstOffset); |
||
2505 | return $rawOffset + $dstOffset; |
||
2506 | // Note: Because we pass in wall millisInDay, rather than |
||
2507 | // standard millisInDay, we interpret "1:00 am" on the day |
||
2508 | // of cessation of DST as "1:00 am Std" (assuming the time |
||
2509 | // of cessation is 2:00 am). |
||
2510 | } |
||
2511 | |||
2512 | /** |
||
2513 | * Determine the best stamp in a range. |
||
2514 | * |
||
2515 | * @param int $first first enum to look at |
||
2516 | * @param int $last last enum to look at |
||
2517 | * @param int $bestStampSoFar stamp prior to function call |
||
2518 | * |
||
2519 | * @return int the stamp value of the best stamp |
||
2520 | * |
||
2521 | * @author Dominik del Bondio <[email protected]> |
||
2522 | * @author The ICU Project |
||
2523 | * @since 0.11.0 |
||
2524 | */ |
||
2525 | protected function newestStamp($first, $last, $bestStampSoFar) |
||
2526 | { |
||
2527 | $bestStamp = $bestStampSoFar; |
||
2528 | for ($i = (int) $first; $i <= (int) $last; ++$i) { |
||
2529 | if ($this->fStamp[$i] > $bestStamp) { |
||
2530 | $bestStamp = $this->fStamp[$i]; |
||
2531 | } |
||
2532 | } |
||
2533 | return $bestStamp; |
||
2534 | } |
||
2535 | |||
2536 | /** |
||
2537 | * @var array Precedence table for Dates |
||
2538 | * @see #resolveFields |
||
2539 | * @internal |
||
2540 | * |
||
2541 | * @author Dominik del Bondio <[email protected]> |
||
2542 | * @author The ICU Project |
||
2543 | * @since 0.11.0 |
||
2544 | */ |
||
2545 | static $kDatePrecedence = array( |
||
0 ignored issues
–
show
The visibility should be declared for property
$kDatePrecedence .
The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using class A {
var $property;
}
the property is implicitly global. To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2. ![]() |
|||
2546 | array( |
||
2547 | array(DateDefinitions::DAY_OF_MONTH, self::RESOLVE_STOP), |
||
2548 | array(DateDefinitions::WEEK_OF_YEAR, DateDefinitions::DAY_OF_WEEK, self::RESOLVE_STOP), |
||
2549 | array(DateDefinitions::WEEK_OF_MONTH, DateDefinitions::DAY_OF_WEEK, self::RESOLVE_STOP), |
||
2550 | array(DateDefinitions::DAY_OF_WEEK_IN_MONTH, DateDefinitions::DAY_OF_WEEK, self::RESOLVE_STOP), |
||
2551 | array(DateDefinitions::WEEK_OF_YEAR, DateDefinitions::DOW_LOCAL, self::RESOLVE_STOP), |
||
2552 | array(DateDefinitions::WEEK_OF_MONTH, DateDefinitions::DOW_LOCAL, self::RESOLVE_STOP), |
||
2553 | array(DateDefinitions::DAY_OF_WEEK_IN_MONTH, DateDefinitions::DOW_LOCAL, self::RESOLVE_STOP), |
||
2554 | array(DateDefinitions::DAY_OF_YEAR, self::RESOLVE_STOP), |
||
2555 | // kResolveRemap | UCAL_DAY_OF_MONTH |
||
2556 | array(37, DateDefinitions::YEAR, self::RESOLVE_STOP), // if YEAR is set over YEAR_WOY use DAY_OF_MONTH |
||
2557 | // kResolveRemap | UCAL_WEEK_OF_YEAR |
||
2558 | array(35, DateDefinitions::YEAR_WOY, self::RESOLVE_STOP), // if YEAR_WOY is set, calc based on WEEK_OF_YEAR |
||
2559 | array(self::RESOLVE_STOP), |
||
2560 | ), |
||
2561 | array( |
||
2562 | array(DateDefinitions::WEEK_OF_YEAR, self::RESOLVE_STOP), |
||
2563 | array(DateDefinitions::WEEK_OF_MONTH, self::RESOLVE_STOP), |
||
2564 | array(DateDefinitions::DAY_OF_WEEK_IN_MONTH, self::RESOLVE_STOP), |
||
2565 | // kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH |
||
2566 | array(40, DateDefinitions::DAY_OF_WEEK, self::RESOLVE_STOP), |
||
2567 | // self::kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
38% 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. ![]() |
|||
2568 | array(40, DateDefinitions::DOW_LOCAL, self::RESOLVE_STOP), |
||
2569 | array(self::RESOLVE_STOP), |
||
2570 | ), |
||
2571 | array( |
||
2572 | array(self::RESOLVE_STOP), |
||
2573 | ), |
||
2574 | ); |
||
2575 | |||
2576 | /** |
||
2577 | * @var array Precedence table for Year |
||
2578 | * @see #resolveFields |
||
2579 | * @internal |
||
2580 | * |
||
2581 | * @author Dominik del Bondio <[email protected]> |
||
2582 | * @author The ICU Project |
||
2583 | * @since 0.11.0 |
||
2584 | */ |
||
2585 | protected static $kYearPrecedence = array( |
||
2586 | array( |
||
2587 | array(DateDefinitions::YEAR, self::RESOLVE_STOP), |
||
2588 | array(DateDefinitions::EXTENDED_YEAR, self::RESOLVE_STOP), |
||
2589 | array(DateDefinitions::YEAR_WOY, DateDefinitions::WEEK_OF_YEAR, self::RESOLVE_STOP), // YEAR_WOY is useless without WEEK_OF_YEAR |
||
2590 | array(self::RESOLVE_STOP), |
||
2591 | ), |
||
2592 | array( |
||
2593 | array(self::RESOLVE_STOP), |
||
2594 | ), |
||
2595 | ); |
||
2596 | |||
2597 | /** |
||
2598 | * @var array Precedence table for Day of Week |
||
2599 | * @see #resolveFields |
||
2600 | * @internal |
||
2601 | * |
||
2602 | * @author Dominik del Bondio <[email protected]> |
||
2603 | * @author The ICU Project |
||
2604 | * @since 0.11.0 |
||
2605 | */ |
||
2606 | protected static $kDOWPrecedence = array( |
||
2607 | array( |
||
2608 | array(DateDefinitions::DAY_OF_WEEK, self::RESOLVE_STOP, self::RESOLVE_STOP), |
||
2609 | array(DateDefinitions::DOW_LOCAL, self::RESOLVE_STOP, self::RESOLVE_STOP), |
||
2610 | array(self::RESOLVE_STOP), |
||
2611 | ), |
||
2612 | array( |
||
2613 | array(self::RESOLVE_STOP), |
||
2614 | ), |
||
2615 | ); |
||
2616 | |||
2617 | /** |
||
2618 | * Given a precedence table, return the newest field combination in |
||
2619 | * the table, or UCAL_FIELD_COUNT if none is found. |
||
2620 | * |
||
2621 | * <p>The precedence table is a 3-dimensional array of integers. It |
||
2622 | * may be thought of as an array of groups. Each group is an array of |
||
2623 | * lines. Each line is an array of field numbers. Within a line, if |
||
2624 | * all fields are set, then the time stamp of the line is taken to be |
||
2625 | * the stamp of the most recently set field. If any field of a line is |
||
2626 | * unset, then the line fails to match. Within a group, the line with |
||
2627 | * the newest time stamp is selected. The first field of the line is |
||
2628 | * returned to indicate which line matched. |
||
2629 | * |
||
2630 | * <p>In some cases, it may be desirable to map a line to field that |
||
2631 | * whose stamp is NOT examined. For example, if the best field is |
||
2632 | * DAY_OF_WEEK then the DAY_OF_WEEK_IN_MONTH algorithm may be used. In |
||
2633 | * order to do this, insert the value <code>kResolveRemap | F</code> at |
||
2634 | * the start of the line, where <code>F</code> is the desired return |
||
2635 | * field value. This field will NOT be examined; it only determines |
||
2636 | * the return value if the other fields in the line are the newest. |
||
2637 | * |
||
2638 | * <p>If all lines of a group contain at least one unset field, then no |
||
2639 | * line will match, and the group as a whole will fail to match. In |
||
2640 | * that case, the next group will be processed. If all groups fail to |
||
2641 | * match, then UCAL_FIELD_COUNT is returned. |
||
2642 | * @internal |
||
2643 | * |
||
2644 | * @param array $precedenceTable the precedence table |
||
2645 | * |
||
2646 | * @return int the best field |
||
2647 | * |
||
2648 | * @author Dominik del Bondio <[email protected]> |
||
2649 | * @author The ICU Project |
||
2650 | * @since 0.11.0 |
||
2651 | */ |
||
2652 | protected function resolveFields($precedenceTable) |
||
2653 | { |
||
2654 | $bestField = DateDefinitions::FIELD_COUNT; |
||
2655 | for ($g = 0; $precedenceTable[$g][0][0] != -1 && ($bestField == DateDefinitions::FIELD_COUNT); ++$g) { |
||
2656 | $bestStamp = self::kUnset; |
||
2657 | for ($l = 0; $precedenceTable[$g][$l][0] != -1; ++$l) { |
||
2658 | $lineStamp = self::kUnset; |
||
2659 | // Skip over first entry if it is negative |
||
2660 | for ($i = (($precedenceTable[$g][$l][0] >= self::RESOLVE_REMAP) ? 1 : 0); $precedenceTable[$g][$l][$i] != -1; ++$i) { |
||
2661 | $s = $this->fStamp[$precedenceTable[$g][$l][$i]]; |
||
2662 | |||
2663 | // If any field is unset then don't use this line |
||
2664 | if ($s == self::kUnset) { |
||
2665 | // goto linesInGroup; |
||
2666 | continue 2; |
||
2667 | } elseif ($s > $lineStamp) { |
||
2668 | $lineStamp = $s; |
||
2669 | } |
||
2670 | } |
||
2671 | // Record new maximum stamp & field no. |
||
2672 | if ($lineStamp > $bestStamp) { |
||
2673 | $bestStamp = $lineStamp; |
||
2674 | $bestField = $precedenceTable[$g][$l][0]; // First field refers to entire line |
||
2675 | } |
||
2676 | //linesInGroup: |
||
2677 | } |
||
2678 | } |
||
2679 | return ($bestField >= self::RESOLVE_REMAP) ? ($bestField & (self::RESOLVE_REMAP - 1)) : $bestField ; |
||
2680 | } |
||
2681 | |||
2682 | /** |
||
2683 | * @return array |
||
2684 | * |
||
2685 | * @author Dominik del Bondio <[email protected]> |
||
2686 | * @author The ICU Project |
||
2687 | * @since 0.11.0 |
||
2688 | */ |
||
2689 | protected function getFieldResolutionTable() |
||
2690 | { |
||
2691 | return self::$kDatePrecedence; |
||
2692 | } |
||
2693 | |||
2694 | /** |
||
2695 | * Return the field that is newer, either defaultField, or alternateField. |
||
2696 | * If neither is newer or neither is set, return defaultField. |
||
2697 | * @internal |
||
2698 | * |
||
2699 | * @param int |
||
2700 | * @param int |
||
2701 | * |
||
2702 | * @return int |
||
2703 | * |
||
2704 | * @author Dominik del Bondio <[email protected]> |
||
2705 | * @author The ICU Project |
||
2706 | * @since 0.11.0 |
||
2707 | */ |
||
2708 | protected function newerField($defaultField, $alternateField) |
||
2709 | { |
||
2710 | if ($this->fStamp[$alternateField] > $this->fStamp[$defaultField]) { |
||
2711 | return $alternateField; |
||
2712 | } |
||
2713 | return $defaultField; |
||
2714 | } |
||
2715 | |||
2716 | /** |
||
2717 | * Helper function for calculating limits by trial and error |
||
2718 | * |
||
2719 | * @param int $field The field being investigated |
||
2720 | * @param int $startValue starting (least max) value of field |
||
2721 | * @param int $endValue ending (greatest max) value of field |
||
2722 | * |
||
2723 | * @return int |
||
2724 | * |
||
2725 | * @author Dominik del Bondio <[email protected]> |
||
2726 | * @author The ICU Project |
||
2727 | * @since 0.11.0 |
||
2728 | */ |
||
2729 | protected function getActualHelper($field, $startValue, $endValue) |
||
2730 | { |
||
2731 | if ($startValue == $endValue) { |
||
2732 | // if we know that the maximum value is always the same, just return it |
||
2733 | return $startValue; |
||
2734 | } |
||
2735 | |||
2736 | $delta = ($endValue > $startValue) ? 1 : -1; |
||
2737 | |||
2738 | // clone the calendar so we don't mess with the real one, and set it to |
||
2739 | // accept anything for the field values |
||
2740 | $work = clone $this; |
||
2741 | $work->setLenient(true); |
||
2742 | $work->prepareGetActual($field, $delta < 0); |
||
2743 | |||
2744 | // now try each value from the start to the end one by one until |
||
2745 | // we get a value that normalizes to another value. The last value that |
||
2746 | // normalizes to itself is the actual maximum for the current date |
||
2747 | $result = $startValue; |
||
2748 | View Code Duplication | do { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
2749 | $work->set($field, $startValue); |
||
2750 | if ($work->get($field) != $startValue) { |
||
2751 | break; |
||
2752 | } else { |
||
2753 | $result = $startValue; |
||
2754 | $startValue += $delta; |
||
2755 | } |
||
2756 | } while ($result != $endValue); |
||
2757 | |||
2758 | return $result; |
||
2759 | } |
||
2760 | |||
2761 | /** |
||
2762 | * @var bool The flag which indicates if the current time is set in the |
||
2763 | * calendar. |
||
2764 | */ |
||
2765 | protected $fIsTimeSet = false; |
||
2766 | |||
2767 | /** |
||
2768 | * @var bool True if the fields are in sync with the currently set time |
||
2769 | * of this Calendar. If false, then the next attempt to get |
||
2770 | * the value of a field will force a recomputation of all |
||
2771 | * fields from the current value of the time field. |
||
2772 | */ |
||
2773 | protected $fAreFieldsInSync = false; |
||
2774 | |||
2775 | /** |
||
2776 | * @var bool True if all of the fields have been set. This is |
||
2777 | * initially false, and set to true by computeFields(). |
||
2778 | */ |
||
2779 | protected $fAreAllFieldsSet = false; |
||
2780 | |||
2781 | /** |
||
2782 | * @var bool True if all fields have been virtually set, but have not |
||
2783 | * yet been computed. This occurs only in setTimeInMillis(). |
||
2784 | * A calendar set to this state will compute all fields from |
||
2785 | * the time if it becomes necessary, but otherwise will delay |
||
2786 | * such computation. |
||
2787 | */ |
||
2788 | protected $fAreFieldsVirtuallySet = false; |
||
2789 | |||
2790 | /** |
||
2791 | * Get the current time without recomputing. |
||
2792 | * |
||
2793 | * @return float the current time without recomputing. |
||
2794 | * |
||
2795 | * @author Dominik del Bondio <[email protected]> |
||
2796 | * @author The ICU Project |
||
2797 | * @since 0.11.0 |
||
2798 | */ |
||
2799 | protected function internalGetTime() |
||
2800 | { |
||
2801 | return $this->fTime; |
||
2802 | } |
||
2803 | |||
2804 | /** |
||
2805 | * Set the current time without affecting flags or fields. |
||
2806 | * |
||
2807 | * @param float $time The time to be set |
||
2808 | * |
||
2809 | * @author Dominik del Bondio <[email protected]> |
||
2810 | * @author The ICU Project |
||
2811 | * @since 0.11.0 |
||
2812 | */ |
||
2813 | protected function internalSetTime($time) |
||
2814 | { |
||
2815 | $this->fTime = $time; |
||
2816 | } |
||
2817 | |||
2818 | /** |
||
2819 | * @var array The time fields containing values into which the millis |
||
2820 | * is computed. |
||
2821 | */ |
||
2822 | protected $fFields; |
||
2823 | |||
2824 | /** |
||
2825 | * @var array The flags which tell if a specified time field for the |
||
2826 | * calendar is set. |
||
2827 | * |
||
2828 | * @author Dominik del Bondio <[email protected]> |
||
2829 | * @author The ICU Project |
||
2830 | * @since 0.11.0 |
||
2831 | * |
||
2832 | * @deprecated ICU 2.8 use (fStamp[n]!=kUnset) |
||
2833 | */ |
||
2834 | protected $fIsSet; |
||
2835 | |||
2836 | /** Special values of stamp[] |
||
2837 | * |
||
2838 | * @author Dominik del Bondio <[email protected]> |
||
2839 | * @author The ICU Project |
||
2840 | * @since 0.11.0 |
||
2841 | */ |
||
2842 | const kUnset = 0; |
||
2843 | const kInternallySet = 1; |
||
2844 | const kMinimumUserStamp = 2; |
||
2845 | |||
2846 | /** |
||
2847 | * @var array Pseudo-time-stamps which specify when each field was set. |
||
2848 | * There are two special values, UNSET and INTERNALLY_SET. |
||
2849 | * Values from MINIMUM_USER_SET to Integer.MAX_VALUE are |
||
2850 | * legal user set values. |
||
2851 | */ |
||
2852 | protected $fStamp; |
||
2853 | |||
2854 | /** |
||
2855 | * Subclasses may override this method to compute several fields |
||
2856 | * specific to each calendar system. These are: |
||
2857 | * |
||
2858 | * <ul><li>DateDefinitions::ERA |
||
2859 | * <li>DateDefinitions::YEAR |
||
2860 | * <li>DateDefinitions::MONTH |
||
2861 | * <li>DateDefinitions::DAY_OF_MONTH |
||
2862 | * <li>DateDefinitions::DAY_OF_YEAR |
||
2863 | * <li>DateDefinitions::EXTENDED_YEAR</ul> |
||
2864 | * |
||
2865 | * Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields, which |
||
2866 | * will be set when this method is called. Subclasses can also call |
||
2867 | * the getGregorianXxx() methods to obtain Gregorian calendar |
||
2868 | * equivalents for the given Julian day. |
||
2869 | * |
||
2870 | * <p>In addition, subclasses should compute any subclass-specific |
||
2871 | * fields, that is, fields from BASE_FIELD_COUNT to |
||
2872 | * getFieldCount() - 1. |
||
2873 | * |
||
2874 | * <p>The default implementation in <code>Calendar</code> implements |
||
2875 | * a pure proleptic Gregorian calendar. |
||
2876 | * @internal |
||
2877 | * |
||
2878 | * @param int $julianDay The julian day |
||
2879 | * |
||
2880 | * @author Dominik del Bondio <[email protected]> |
||
2881 | * @author The ICU Project |
||
2882 | * @since 0.11.0 |
||
2883 | */ |
||
2884 | protected function handleComputeFields($julianDay) |
||
2885 | { |
||
2886 | $this->internalSet(DateDefinitions::MONTH, $this->getGregorianMonth()); |
||
2887 | $this->internalSet(DateDefinitions::DAY_OF_MONTH, $this->getGregorianDayOfMonth()); |
||
2888 | $this->internalSet(DateDefinitions::DAY_OF_YEAR, $this->getGregorianDayOfYear()); |
||
2889 | $eyear = $this->getGregorianYear(); |
||
2890 | $this->internalSet(DateDefinitions::EXTENDED_YEAR, $eyear); |
||
2891 | $era = GregorianCalendar::AD; |
||
2892 | if ($eyear < 1) { |
||
2893 | $era = GregorianCalendar::BC; |
||
2894 | $eyear = 1 - $eyear; |
||
2895 | } |
||
2896 | $this->internalSet(DateDefinitions::ERA, $era); |
||
2897 | $this->internalSet(DateDefinitions::YEAR, $eyear); |
||
2898 | } |
||
2899 | |||
2900 | /** |
||
2901 | * Return the extended year on the Gregorian calendar as computed by |
||
2902 | * <code>computeGregorianFields()</code>. |
||
2903 | * @see Calendar::computeGregorianFields |
||
2904 | * @internal |
||
2905 | * |
||
2906 | * @return int The gregorian year |
||
2907 | * |
||
2908 | * @author Dominik del Bondio <[email protected]> |
||
2909 | * @author The ICU Project |
||
2910 | * @since 0.11.0 |
||
2911 | */ |
||
2912 | protected function getGregorianYear() |
||
2913 | { |
||
2914 | return $this->fGregorianYear; |
||
2915 | } |
||
2916 | |||
2917 | /** |
||
2918 | * Return the month (0-based) on the Gregorian calendar as computed by |
||
2919 | * <code>computeGregorianFields()</code>. |
||
2920 | * @see Calendar::computeGregorianFields |
||
2921 | * @internal |
||
2922 | * |
||
2923 | * @return int The gregorian month |
||
2924 | * |
||
2925 | * @author Dominik del Bondio <[email protected]> |
||
2926 | * @author The ICU Project |
||
2927 | * @since 0.11.0 |
||
2928 | */ |
||
2929 | protected function getGregorianMonth() |
||
2930 | { |
||
2931 | return $this->fGregorianMonth; |
||
2932 | } |
||
2933 | |||
2934 | /** |
||
2935 | * Return the day of year (1-based) on the Gregorian calendar as |
||
2936 | * computed by <code>computeGregorianFields()</code>. |
||
2937 | * @see Calendar::computeGregorianFields |
||
2938 | * @internal |
||
2939 | * |
||
2940 | * @return int The gregorian day of year |
||
2941 | * |
||
2942 | * @author Dominik del Bondio <[email protected]> |
||
2943 | * @author The ICU Project |
||
2944 | * @since 0.11.0 |
||
2945 | */ |
||
2946 | protected function getGregorianDayOfYear() |
||
2947 | { |
||
2948 | return $this->fGregorianDayOfYear; |
||
2949 | } |
||
2950 | |||
2951 | /** |
||
2952 | * Return the day of month (1-based) on the Gregorian calendar as |
||
2953 | * computed by <code>computeGregorianFields()</code>. |
||
2954 | * @see Calendar::computeGregorianFields |
||
2955 | * @internal |
||
2956 | * |
||
2957 | * @return int The gregorian day of month |
||
2958 | * |
||
2959 | * @author Dominik del Bondio <[email protected]> |
||
2960 | * @author The ICU Project |
||
2961 | * @since 0.11.0 |
||
2962 | */ |
||
2963 | protected function getGregorianDayOfMonth() |
||
2964 | { |
||
2965 | return $this->fGregorianDayOfMonth; |
||
2966 | } |
||
2967 | |||
2968 | /** |
||
2969 | * Called by computeJulianDay. Returns the default month (0-based) for the |
||
2970 | * year, taking year and era into account. Defaults to 0 for Gregorian, which |
||
2971 | * doesn't care. |
||
2972 | * |
||
2973 | * @return int The default month for the year. |
||
2974 | * |
||
2975 | * @author Dominik del Bondio <[email protected]> |
||
2976 | * @author The ICU Project |
||
2977 | * @since 0.11.0 |
||
2978 | */ |
||
2979 | protected function getDefaultMonthInYear() |
||
2980 | { |
||
2981 | return 0; |
||
2982 | } |
||
2983 | |||
2984 | /** |
||
2985 | * Called by computeJulianDay. Returns the default day (1-based) for the |
||
2986 | * month, taking currently-set year and era into account. Defaults to 1 for |
||
2987 | * Gregorian. |
||
2988 | * |
||
2989 | * @param int $month The months |
||
2990 | * |
||
2991 | * @return int The default day for the month |
||
2992 | * |
||
2993 | * @author Dominik del Bondio <[email protected]> |
||
2994 | * @author The ICU Project |
||
2995 | * @since 0.11.0 |
||
2996 | */ |
||
2997 | protected function getDefaultDayInMonth($month) |
||
0 ignored issues
–
show
|
|||
2998 | { |
||
2999 | return 1; |
||
3000 | } |
||
3001 | |||
3002 | //------------------------------------------------------------------------- |
||
3003 | // Protected utility methods for use by subclasses. These are very handy |
||
3004 | // for implementing add, roll, and computeFields. |
||
3005 | //------------------------------------------------------------------------- |
||
3006 | |||
3007 | /** |
||
3008 | * Adjust the specified field so that it is within |
||
3009 | * the allowable range for the date to which this calendar is set. |
||
3010 | * For example, in a Gregorian calendar pinning the |
||
3011 | * DateDefinitions::DAY_OF_MONTH field for a calendar set to April 31 |
||
3012 | * would cause it to be set to April 30. |
||
3013 | * <p> |
||
3014 | * <b>Subclassing:</b> |
||
3015 | * <br> |
||
3016 | * This utility method is intended for use by subclasses that need to |
||
3017 | * implement their own overrides of {@link #roll roll} and {@link #add add}. |
||
3018 | * <p> |
||
3019 | * <b>Note:</b> |
||
3020 | * <code>pinField</code> is implemented in terms of |
||
3021 | * {@link #getActualMinimum getActualMinimum} |
||
3022 | * and {@link #getActualMaximum getActualMaximum}. If either of those methods |
||
3023 | * uses a slow, iterative algorithm for a particular field, it would be |
||
3024 | * unwise to attempt to call <code>pinField</code> for that field. If you |
||
3025 | * really do need to do so, you should override this method to do |
||
3026 | * something more efficient for that field. |
||
3027 | * <p> |
||
3028 | * |
||
3029 | * @param string $field The calendar field whose value should be pinned. |
||
3030 | * |
||
3031 | * @see getActualMinimum |
||
3032 | * @see getActualMaximum |
||
3033 | * |
||
3034 | * @author Dominik del Bondio <[email protected]> |
||
3035 | * @author The ICU Project |
||
3036 | * @since 0.11.0 |
||
3037 | */ |
||
3038 | protected function pinField($field) |
||
3039 | { |
||
3040 | $max = $this->getActualMaximum($field); |
||
3041 | $min = $this->getActualMinimum($field); |
||
3042 | |||
3043 | if ($this->fFields[$field] > $max) { |
||
3044 | $this->set($field, $max); |
||
3045 | } elseif ($this->fFields[$field] < $min) { |
||
3046 | $this->set($field, $min); |
||
3047 | } |
||
3048 | } |
||
3049 | |||
3050 | /** |
||
3051 | * Return the week number of a day, within a period. This may be the week |
||
3052 | * number in a year or the week number in a month. Usually this will be a |
||
3053 | * value >= 1, but if some initial days of the period are excluded from |
||
3054 | * week 1, because getMinimalDaysInFirstWeek is > 1, then the week number will |
||
3055 | * be zero for those initial days. This method requires the day number and day |
||
3056 | * of week for some known date in the period in order to determine the day of |
||
3057 | * week on the desired day. |
||
3058 | * <p> |
||
3059 | * <b>Subclassing:</b> |
||
3060 | * <br> |
||
3061 | * This method is intended for use by subclasses in implementing their |
||
3062 | * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods. |
||
3063 | * It is often useful in {@link #getActualMinimum getActualMinimum} and |
||
3064 | * {@link #getActualMaximum getActualMaximum} as well. |
||
3065 | * <p> |
||
3066 | * This variant is handy for computing the week number of some other |
||
3067 | * day of a period (often the first or last day of the period) when its day |
||
3068 | * of the week is not known but the day number and day of week for some other |
||
3069 | * day in the period (e.g. the current date) <em>is</em> known. |
||
3070 | * <p> |
||
3071 | * |
||
3072 | * @param int $desiredDay The {@link #UCalendarDateFields DAY_OF_YEAR} or |
||
3073 | * {@link #UCalendarDateFields DAY_OF_MONTH} whose week |
||
3074 | * number is desired. |
||
3075 | * Should be 1 for the first day of the period. |
||
3076 | * |
||
3077 | * @param int $dayOfPeriod The {@link #UCalendarDateFields DAY_OF_YEAR} |
||
3078 | * or {@link #UCalendarDateFields DAY_OF_MONTH} for a day in |
||
3079 | * the period whose {@link #UCalendarDateFields DAY_OF_WEEK} |
||
3080 | * is specified by the <code>knownDayOfWeek</code> parameter. |
||
3081 | * Should be 1 for first day of period. |
||
3082 | * |
||
3083 | * @param int $dayOfWeek The {@link #UCalendarDateFields DAY_OF_WEEK} for the day |
||
3084 | * corresponding to the <code>knownDayOfPeriod</code> |
||
3085 | * parameter. |
||
3086 | * 1-based with 1=Sunday. |
||
3087 | * |
||
3088 | * @return int The week number (one-based), or zero if the day falls |
||
3089 | * before the first week because |
||
3090 | * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} |
||
3091 | * is more than one. |
||
3092 | * |
||
3093 | * @author Dominik del Bondio <[email protected]> |
||
3094 | * @author The ICU Project |
||
3095 | * @since 0.11.0 |
||
3096 | */ |
||
3097 | protected function weekNumber1($desiredDay, $dayOfPeriod, $dayOfWeek) |
||
3098 | { |
||
3099 | // Determine the day of the week of the first day of the period |
||
3100 | // in question (either a year or a month). Zero represents the |
||
3101 | // first day of the week on this calendar. |
||
3102 | $periodStartDayOfWeek = ($dayOfWeek - $this->getFirstDayOfWeek() - $dayOfPeriod + 1) % 7; |
||
3103 | if ($periodStartDayOfWeek < 0) { |
||
3104 | $periodStartDayOfWeek += 7; |
||
3105 | } |
||
3106 | |||
3107 | // Compute the week number. Initially, ignore the first week, which |
||
3108 | // may be fractional (or may not be). We add periodStartDayOfWeek in |
||
3109 | // order to fill out the first week, if it is fractional. |
||
3110 | $weekNo = (int) (($desiredDay + $periodStartDayOfWeek - 1) / 7); |
||
3111 | |||
3112 | // If the first week is long enough, then count it. If |
||
3113 | // the minimal days in the first week is one, or if the period start |
||
3114 | // is zero, we always increment weekNo. |
||
3115 | if ((7 - $periodStartDayOfWeek) >= $this->getMinimalDaysInFirstWeek()) { |
||
3116 | ++$weekNo; |
||
3117 | } |
||
3118 | |||
3119 | return $weekNo; |
||
3120 | } |
||
3121 | |||
3122 | /** |
||
3123 | * Return the week number of a day, within a period. This may be the week number in |
||
3124 | * a year, or the week number in a month. Usually this will be a value >= 1, but if |
||
3125 | * some initial days of the period are excluded from week 1, because |
||
3126 | * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1, |
||
3127 | * then the week number will be zero for those |
||
3128 | * initial days. This method requires the day of week for the given date in order to |
||
3129 | * determine the result. |
||
3130 | * <p> |
||
3131 | * <b>Subclassing:</b> |
||
3132 | * <br> |
||
3133 | * This method is intended for use by subclasses in implementing their |
||
3134 | * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods. |
||
3135 | * It is often useful in {@link #getActualMinimum getActualMinimum} and |
||
3136 | * {@link #getActualMaximum getActualMaximum} as well. |
||
3137 | * <p> |
||
3138 | * @param int $dayOfPeriod The {@link #UCalendarDateFields DAY_OF_YEAR} or |
||
3139 | * {@link #UCalendarDateFields DAY_OF_MONTH} whose week |
||
3140 | * number is desired. Should be 1 for the first day of the |
||
3141 | * period. |
||
3142 | * |
||
3143 | * @param int $dayOfWeek The {@link #UCalendarDateFields DAY_OF_WEEK} for the day |
||
3144 | * corresponding to the <code>dayOfPeriod</code> parameter. |
||
3145 | * 1-based with 1=Sunday. |
||
3146 | * |
||
3147 | * @return int The week number (one-based), or zero if the day falls |
||
3148 | * before the first week because |
||
3149 | * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} |
||
3150 | * is more than one. |
||
3151 | * @internal |
||
3152 | * |
||
3153 | * @author Dominik del Bondio <[email protected]> |
||
3154 | * @author The ICU Project |
||
3155 | * @since 0.11.0 |
||
3156 | */ |
||
3157 | protected function weekNumber($dayOfPeriod, $dayOfWeek) |
||
3158 | { |
||
3159 | return $this->weekNumber1($dayOfPeriod, $dayOfPeriod, $dayOfWeek); |
||
3160 | } |
||
3161 | |||
3162 | /** |
||
3163 | * returns the local DOW, valid range 0..6 |
||
3164 | * @internal |
||
3165 | * |
||
3166 | * @return int |
||
3167 | * |
||
3168 | * @author Dominik del Bondio <[email protected]> |
||
3169 | * @author The ICU Project |
||
3170 | * @since 0.11.0 |
||
3171 | */ |
||
3172 | protected function getLocalDOW() |
||
3173 | { |
||
3174 | // Get zero-based localized DOW, valid range 0..6. This is the DOW |
||
3175 | // we are looking for. |
||
3176 | $dowLocal = 0; |
||
3177 | switch ($this->resolveFields(self::$kDOWPrecedence)) { |
||
3178 | case DateDefinitions::DAY_OF_WEEK: |
||
3179 | $dowLocal = $this->internalGet(DateDefinitions::DAY_OF_WEEK) - $this->fFirstDayOfWeek; |
||
3180 | break; |
||
3181 | case DateDefinitions::DOW_LOCAL: |
||
3182 | $dowLocal = $this->internalGet(DateDefinitions::DOW_LOCAL) - 1; |
||
3183 | break; |
||
3184 | default: |
||
3185 | break; |
||
3186 | } |
||
3187 | $dowLocal = $dowLocal % 7; |
||
3188 | if ($dowLocal < 0) { |
||
3189 | $dowLocal += 7; |
||
3190 | } |
||
3191 | return $dowLocal; |
||
3192 | } |
||
3193 | |||
3194 | /** |
||
3195 | * @var int The next available value for fStamp[] |
||
3196 | */ |
||
3197 | private $fNextStamp = 1;// = MINIMUM_USER_STAMP; |
||
3198 | |||
3199 | /** |
||
3200 | * @var float The current time set for the calendar. |
||
3201 | */ |
||
3202 | private $fTime; |
||
3203 | |||
3204 | /** |
||
3205 | * @see #setLenient |
||
3206 | * @var bool |
||
3207 | */ |
||
3208 | private $fLenient; |
||
3209 | |||
3210 | /** |
||
3211 | * @var TimeZone Time zone affects the time calculation done by |
||
3212 | * Calendar. Calendar subclasses use the time zone |
||
3213 | * data to produce the local time. |
||
3214 | */ |
||
3215 | private $fZone; |
||
3216 | |||
3217 | /** |
||
3218 | * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent. They are |
||
3219 | * used to figure out the week count for a specific date for a given locale. These |
||
3220 | * must be set when a Calendar is constructed. For example, in US locale, |
||
3221 | * firstDayOfWeek is SUNDAY; minimalDaysInFirstWeek is 1. They are used to figure |
||
3222 | * out the week count for a specific date for a given locale. These must be set when |
||
3223 | * a Calendar is constructed. |
||
3224 | * |
||
3225 | * @author Dominik del Bondio <[email protected]> |
||
3226 | * @author The ICU Project |
||
3227 | * @since 0.11.0 |
||
3228 | */ |
||
3229 | private $fFirstDayOfWeek; |
||
3230 | private $fMinimalDaysInFirstWeek; |
||
3231 | |||
3232 | /** |
||
3233 | * Sets firstDayOfWeek and minimalDaysInFirstWeek. Called at Calendar construction |
||
3234 | * time. |
||
3235 | * |
||
3236 | * @param Locale $desiredLocale The given locale. |
||
3237 | * @param string $type The calendar type identifier, e.g: gregorian, |
||
3238 | * buddhist, etc. |
||
3239 | * |
||
3240 | * @author Dominik del Bondio <[email protected]> |
||
3241 | * @author The ICU Project |
||
3242 | * @since 0.11.0 |
||
3243 | */ |
||
3244 | private function setWeekCountData(Locale $desiredLocale, $type) |
||
0 ignored issues
–
show
|
|||
3245 | { |
||
3246 | // Read the week count data from the resource bundle. This should |
||
3247 | // have the form: |
||
3248 | // |
||
3249 | // DateTimeElements:intvector { |
||
3250 | // 1, // first day of week |
||
3251 | // 1 // min days in week |
||
3252 | // } |
||
3253 | // Both have a range of 1..7 |
||
3254 | |||
3255 | $this->fFirstDayOfWeek = DateDefinitions::SUNDAY; |
||
3256 | $this->fMinimalDaysInFirstWeek = 1; |
||
3257 | |||
3258 | $tm = $desiredLocale->getContext()->getTranslationManager(); |
||
3259 | $cdata = $tm->getTerritoryData($desiredLocale->getLocaleTerritory()); |
||
3260 | if (isset($cdata['week']['firstDay'])) { |
||
3261 | $this->fFirstDayOfWeek = (int) $cdata['week']['firstDay']; |
||
3262 | } |
||
3263 | if (isset($cdata['week']['minDays'])) { |
||
3264 | $this->fMinimalDaysInFirstWeek = (int) $cdata['week']['minDays']; |
||
3265 | } |
||
3266 | } |
||
3267 | |||
3268 | /** |
||
3269 | * Recompute the time and update the status fields isTimeSet |
||
3270 | * and areFieldsSet. Callers should check isTimeSet and only |
||
3271 | * call this method if isTimeSet is false. |
||
3272 | * |
||
3273 | * @author Dominik del Bondio <[email protected]> |
||
3274 | * @author The ICU Project |
||
3275 | * @since 0.11.0 |
||
3276 | */ |
||
3277 | private function updateTime() |
||
3278 | { |
||
3279 | $this->computeTime(); |
||
3280 | |||
3281 | // If we are lenient, we need to recompute the fields to normalize |
||
3282 | // the values. Also, if we haven't set all the fields yet (i.e., |
||
3283 | // in a newly-created object), we need to fill in the fields. [LIU] |
||
3284 | if ($this->isLenient() || ! $this->fAreAllFieldsSet) { |
||
3285 | $this->fAreFieldsInSync = false; |
||
3286 | } |
||
3287 | |||
3288 | $this->fIsTimeSet = true; |
||
3289 | $this->fAreFieldsVirtuallySet = false; |
||
3290 | } |
||
3291 | |||
3292 | /** |
||
3293 | * @var int The Gregorian year, as computed by computeGregorianFields() |
||
3294 | * and returned by getGregorianYear(). |
||
3295 | * @see Calendar::computeGregorianFields |
||
3296 | */ |
||
3297 | private $fGregorianYear; |
||
3298 | |||
3299 | /** |
||
3300 | * @var int The Gregorian month, as computed by |
||
3301 | * computeGregorianFields() and returned by |
||
3302 | * getGregorianMonth(). |
||
3303 | * @see Calendar::computeGregorianFields |
||
3304 | */ |
||
3305 | private $fGregorianMonth; |
||
3306 | |||
3307 | /** |
||
3308 | * @var int The Gregorian day of the year, as computed by |
||
3309 | * computeGregorianFields() and returned by |
||
3310 | * getGregorianDayOfYear(). |
||
3311 | * @see Calendar::computeGregorianFields |
||
3312 | */ |
||
3313 | private $fGregorianDayOfYear; |
||
3314 | |||
3315 | /** |
||
3316 | * @var int The Gregorian day of the month, as computed by |
||
3317 | * computeGregorianFields() and returned by |
||
3318 | * getGregorianDayOfMonth(). |
||
3319 | * @see Calendar::computeGregorianFields |
||
3320 | */ |
||
3321 | private $fGregorianDayOfMonth; |
||
3322 | |||
3323 | /* calculations */ |
||
3324 | |||
3325 | /** |
||
3326 | * Compute the Gregorian calendar year, month, and day of month from |
||
3327 | * the given Julian day. These values are not stored in fields, but in |
||
3328 | * member variables gregorianXxx. Also compute the DAY_OF_WEEK and |
||
3329 | * DOW_LOCAL fields. |
||
3330 | * |
||
3331 | * @param int $julianDay The julian day |
||
3332 | * |
||
3333 | * @author Dominik del Bondio <[email protected]> |
||
3334 | * @author The ICU Project |
||
3335 | * @since 0.11.0 |
||
3336 | */ |
||
3337 | private function computeGregorianAndDOWFields($julianDay) |
||
3338 | { |
||
3339 | $this->computeGregorianFields($julianDay); |
||
3340 | |||
3341 | // Compute day of week: JD 0 = Monday |
||
3342 | $dow = $this->julianDayToDayOfWeek($julianDay); |
||
3343 | $this->internalSet(DateDefinitions::DAY_OF_WEEK, $dow); |
||
3344 | |||
3345 | // Calculate 1-based localized day of week |
||
3346 | $dowLocal = $dow - $this->getFirstDayOfWeek() + 1; |
||
3347 | if ($dowLocal < 1) { |
||
3348 | $dowLocal += 7; |
||
3349 | } |
||
3350 | $this->internalSet(DateDefinitions::DOW_LOCAL, $dowLocal); |
||
3351 | $this->fFields[DateDefinitions::DOW_LOCAL] = $dowLocal; |
||
3352 | } |
||
3353 | |||
3354 | /** |
||
3355 | * Compute the Gregorian calendar year, month, and day of month from the |
||
3356 | * Julian day. These values are not stored in fields, but in member |
||
3357 | * variables gregorianXxx. They are used for time zone computations and by |
||
3358 | * subclasses that are Gregorian derivatives. Subclasses may call this |
||
3359 | * method to perform a Gregorian calendar millis->fields computation. |
||
3360 | * To perform a Gregorian calendar fields->millis computation, call |
||
3361 | * computeGregorianMonthStart(). |
||
3362 | * @see #computeGregorianMonthStart |
||
3363 | * |
||
3364 | * @param int $julianDay The julian day |
||
3365 | * |
||
3366 | * @author Dominik del Bondio <[email protected]> |
||
3367 | * @author The ICU Project |
||
3368 | * @since 0.11.0 |
||
3369 | */ |
||
3370 | private function computeGregorianFields($julianDay) |
||
3371 | { |
||
3372 | $gregorianDayOfWeekUnused = 0; |
||
3373 | CalendarGrego::dayToFields($julianDay - DateDefinitions::EPOCH_START_AS_JULIAN_DAY, $this->fGregorianYear, $this->fGregorianMonth, $this->fGregorianDayOfMonth, $gregorianDayOfWeekUnused, $this->fGregorianDayOfYear); |
||
3374 | } |
||
3375 | |||
3376 | /** |
||
3377 | * Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH, |
||
3378 | * DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR, |
||
3379 | * DAY_OF_WEEK, and DAY_OF_YEAR. The latter fields are computed by the |
||
3380 | * subclass based on the calendar system. |
||
3381 | * |
||
3382 | * <p>The YEAR_WOY field is computed simplistically. It is equal to YEAR |
||
3383 | * most of the time, but at the year boundary it may be adjusted to YEAR-1 |
||
3384 | * or YEAR+1 to reflect the overlap of a week into an adjacent year. In |
||
3385 | * this case, a simple increment or decrement is performed on YEAR, even |
||
3386 | * though this may yield an invalid YEAR value. For instance, if the YEAR |
||
3387 | * is part of a calendar system with an N-year cycle field CYCLE, then |
||
3388 | * incrementing the YEAR may involve incrementing CYCLE and setting YEAR |
||
3389 | * back to 0 or 1. This is not handled by this code, and in fact cannot be |
||
3390 | * simply handled without having subclasses define an entire parallel set of |
||
3391 | * fields for fields larger than or equal to a year. This additional |
||
3392 | * complexity is not warranted, since the intention of the YEAR_WOY field is |
||
3393 | * to support ISO 8601 notation, so it will typically be used with a |
||
3394 | * proleptic Gregorian calendar, which has no field larger than a year. |
||
3395 | * |
||
3396 | * @author Dominik del Bondio <[email protected]> |
||
3397 | * @author The ICU Project |
||
3398 | * @since 0.11.0 |
||
3399 | */ |
||
3400 | private function computeWeekFields() |
||
3401 | { |
||
3402 | $eyear = $this->fFields[DateDefinitions::EXTENDED_YEAR]; |
||
3403 | $year = $this->fFields[DateDefinitions::YEAR]; |
||
3404 | $dayOfWeek = $this->fFields[DateDefinitions::DAY_OF_WEEK]; |
||
3405 | $dayOfYear = $this->fFields[DateDefinitions::DAY_OF_YEAR]; |
||
3406 | |||
3407 | // WEEK_OF_YEAR start |
||
3408 | // Compute the week of the year. For the Gregorian calendar, valid week |
||
3409 | // numbers run from 1 to 52 or 53, depending on the year, the first day |
||
3410 | // of the week, and the minimal days in the first week. For other |
||
3411 | // calendars, the valid range may be different -- it depends on the year |
||
3412 | // length. Days at the start of the year may fall into the last week of |
||
3413 | // the previous year; days at the end of the year may fall into the |
||
3414 | // first week of the next year. ASSUME that the year length is less than |
||
3415 | // 7000 days. |
||
3416 | $yearOfWeekOfYear = $year; |
||
3417 | $relDow = ($dayOfWeek + 7 - $this->getFirstDayOfWeek()) % 7; // 0..6 |
||
3418 | $relDowJan1 = ($dayOfWeek - $dayOfYear + 7001 - $this->getFirstDayOfWeek()) % 7; // 0..6 |
||
3419 | $woy = (int) (($dayOfYear - 1 + $relDowJan1) / 7); // 0..53 |
||
3420 | if ((7 - $relDowJan1) >= $this->getMinimalDaysInFirstWeek()) { |
||
3421 | ++$woy; |
||
3422 | } |
||
3423 | |||
3424 | // Adjust for weeks at the year end that overlap into the previous or |
||
3425 | // next calendar year. |
||
3426 | if ($woy == 0) { |
||
3427 | // We are the last week of the previous year. |
||
3428 | // Check to see if we are in the last week; if so, we need |
||
3429 | // to handle the case in which we are the first week of the |
||
3430 | // next year. |
||
3431 | |||
3432 | $prevDoy = $dayOfYear + $this->handleGetYearLength($eyear - 1); |
||
3433 | $woy = $this->weekNumber($prevDoy, $dayOfWeek); |
||
3434 | $yearOfWeekOfYear--; |
||
3435 | } else { |
||
3436 | $lastDoy = $this->handleGetYearLength($eyear); |
||
3437 | // Fast check: For it to be week 1 of the next year, the DOY |
||
3438 | // must be on or after L-5, where L is yearLength(), then it |
||
3439 | // cannot possibly be week 1 of the next year: |
||
3440 | // L-5 L |
||
3441 | // doy: 359 360 361 362 363 364 365 001 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
45% 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. ![]() |
|||
3442 | // dow: 1 2 3 4 5 6 7 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
44% 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. ![]() |
|||
3443 | if ($dayOfYear >= ($lastDoy - 5)) { |
||
3444 | $lastRelDow = ($relDow + $lastDoy - $dayOfYear) % 7; |
||
3445 | if ($lastRelDow < 0) { |
||
3446 | $lastRelDow += 7; |
||
3447 | } |
||
3448 | if (((6 - $lastRelDow) >= $this->getMinimalDaysInFirstWeek()) && |
||
3449 | (($dayOfYear + 7 - $relDow) > $lastDoy)) { |
||
3450 | $woy = 1; |
||
3451 | $yearOfWeekOfYear++; |
||
3452 | } |
||
3453 | } |
||
3454 | } |
||
3455 | $this->fFields[DateDefinitions::WEEK_OF_YEAR] = $woy; |
||
3456 | $this->fFields[DateDefinitions::YEAR_WOY] = $yearOfWeekOfYear; |
||
3457 | // WEEK_OF_YEAR end |
||
3458 | |||
3459 | $dayOfMonth = $this->fFields[DateDefinitions::DAY_OF_MONTH]; |
||
3460 | $this->fFields[DateDefinitions::WEEK_OF_MONTH] = $this->weekNumber($dayOfMonth, $dayOfWeek); |
||
3461 | $this->fFields[DateDefinitions::DAY_OF_WEEK_IN_MONTH] = (int)(($dayOfMonth-1) / 7) + 1; |
||
3462 | } |
||
3463 | |||
3464 | /** |
||
3465 | * Ensure that each field is within its valid range by calling {@link |
||
3466 | * #validateField(int, int&)} on each field that has been set. This method |
||
3467 | * should only be called if this calendar is not lenient. |
||
3468 | * @see #isLenient |
||
3469 | * @see #validateField(int, int&) |
||
3470 | * @internal |
||
3471 | * |
||
3472 | * @author Dominik del Bondio <[email protected]> |
||
3473 | * @author The ICU Project |
||
3474 | * @since 0.11.0 |
||
3475 | */ |
||
3476 | private function validateFields() |
||
3477 | { |
||
3478 | for ($field = 0; $field < DateDefinitions::FIELD_COUNT; ++$field) { |
||
3479 | if ($this->_isSet($field)) { |
||
3480 | $this->validateField($field); |
||
3481 | } |
||
3482 | } |
||
3483 | } |
||
3484 | |||
3485 | /** |
||
3486 | * Validate a single field of this calendar. Subclasses should |
||
3487 | * override this method to validate any calendar-specific fields. |
||
3488 | * Generic fields can be handled by |
||
3489 | * <code>Calendar.validateField()</code>. |
||
3490 | * @see #validateField(int, int, int, int&) |
||
3491 | * @internal |
||
3492 | * |
||
3493 | * @param int $field The field |
||
3494 | * |
||
3495 | * @author Dominik del Bondio <[email protected]> |
||
3496 | * @author The ICU Project |
||
3497 | * @since 0.11.0 |
||
3498 | */ |
||
3499 | private function validateField($field) |
||
3500 | { |
||
3501 | switch ($field) { |
||
3502 | case DateDefinitions::DAY_OF_MONTH: |
||
3503 | $y = $this->handleGetExtendedYear(); |
||
3504 | $this->validateField1($field, 1, $this->handleGetMonthLength($y, $this->internalGet(DateDefinitions::MONTH))); |
||
3505 | break; |
||
3506 | case DateDefinitions::DAY_OF_YEAR: |
||
3507 | $y = $this->handleGetExtendedYear(); |
||
3508 | $this->validateField1($field, 1, $this->handleGetYearLength($y)); |
||
3509 | break; |
||
3510 | case DateDefinitions::DAY_OF_WEEK_IN_MONTH: |
||
3511 | if ($this->internalGet($field) == 0) { |
||
3512 | throw new \InvalidArgumentException('DAY_OF_WEEK_IN_MONTH cannot be zero'); |
||
3513 | } |
||
3514 | $this->validateField1($field, $this->getMinimum($field), $this->getMaximum($field)); |
||
3515 | break; |
||
3516 | default: |
||
3517 | $this->validateField1($field, $this->getMinimum($field), $this->getMaximum($field)); |
||
3518 | break; |
||
3519 | } |
||
3520 | } |
||
3521 | |||
3522 | /** |
||
3523 | * Validate a single field of this calendar given its minimum and |
||
3524 | * maximum allowed value. If the field is out of range, |
||
3525 | * <code>InvalidArgumentException</code> will be thrown. Subclasses may |
||
3526 | * use this method in their implementation of {@link |
||
3527 | * #validateField(int, int&)}. |
||
3528 | * @internal |
||
3529 | * |
||
3530 | * @throws <b>InvalidArgumentException</b> |
||
3531 | * |
||
3532 | * @param string |
||
3533 | * @param int |
||
3534 | * @param int |
||
3535 | * |
||
3536 | * @author Dominik del Bondio <[email protected]> |
||
3537 | * @author The ICU Project |
||
3538 | * @since 0.11.0 |
||
3539 | */ |
||
3540 | private function validateField1($field, $min, $max) |
||
3541 | { |
||
3542 | $value = $this->fFields[$field]; |
||
3543 | if ($value < $min || $value > $max) { |
||
3544 | throw new \InvalidArgumentException('Illegal argument error. Field: ' . $field . '. Value ' . $value . ' is not within ' . $min . ' and ' . $max); |
||
3545 | } |
||
3546 | } |
||
3547 | |||
3548 | /** |
||
3549 | * Convert a quasi Julian date to the day of the week. The Julian date used here is |
||
3550 | * not a true Julian date, since it is measured from midnight, not noon. Return |
||
3551 | * value is one-based. |
||
3552 | * |
||
3553 | * @param double $julian The given Julian date number. |
||
3554 | * |
||
3555 | * @return int Day number from 1..7 (SUN..SAT). |
||
3556 | * |
||
3557 | * @internal |
||
3558 | * |
||
3559 | * @author Dominik del Bondio <[email protected]> |
||
3560 | * @author The ICU Project |
||
3561 | * @since 0.11.0 |
||
3562 | */ |
||
3563 | protected function julianDayToDayOfWeek($julian) |
||
3564 | { |
||
3565 | // If julian is negative, then julian%7 will be negative, so we adjust |
||
3566 | // accordingly. We add 1 because Julian day 0 is Monday. |
||
3567 | |||
3568 | $dayOfWeek = fmod($julian + 1, 7); |
||
3569 | |||
3570 | $result = ($dayOfWeek + (($dayOfWeek < 0) ? (7 + DateDefinitions::SUNDAY) : DateDefinitions::SUNDAY)); |
||
3571 | return $result; |
||
3572 | } |
||
3573 | |||
3574 | /** |
||
3575 | * @var string |
||
3576 | */ |
||
3577 | private $validLocale; |
||
0 ignored issues
–
show
|
|||
3578 | |||
3579 | /** |
||
3580 | * @var string |
||
3581 | */ |
||
3582 | private $actualLocale; |
||
0 ignored issues
–
show
|
|||
3583 | |||
3584 | /** |
||
3585 | * @internal |
||
3586 | * @return bool if this calendar has a default century (i.e. 03 -> 2003) |
||
3587 | * |
||
3588 | * @author Dominik del Bondio <[email protected]> |
||
3589 | * @author The ICU Project |
||
3590 | * @since 0.11.0 |
||
3591 | */ |
||
3592 | abstract public function haveDefaultCentury(); |
||
3593 | |||
3594 | /** |
||
3595 | * @internal |
||
3596 | * @return float the start of the default century, as a UDate |
||
3597 | * |
||
3598 | * @author Dominik del Bondio <[email protected]> |
||
3599 | * @author The ICU Project |
||
3600 | * @since 0.11.0 |
||
3601 | */ |
||
3602 | abstract public function defaultCenturyStart(); |
||
3603 | |||
3604 | /** |
||
3605 | * @internal |
||
3606 | * @return int the beginning year of the default century, as a year |
||
3607 | * |
||
3608 | * @author Dominik del Bondio <[email protected]> |
||
3609 | * @author The ICU Project |
||
3610 | * @since 0.11.0 |
||
3611 | */ |
||
3612 | abstract public function defaultCenturyStartYear(); |
||
3613 | |||
3614 | /** |
||
3615 | * Returns the type of the implementing calendar. |
||
3616 | * |
||
3617 | * @return string The type of this calendar (Gregorian, ...) |
||
3618 | * |
||
3619 | * @author Dominik del Bondio <[email protected]> |
||
3620 | * @since 0.11.0 |
||
3621 | */ |
||
3622 | abstract public function getType(); |
||
3623 | } |
||
3624 |
This check looks for assignments to scalar types that may be of the wrong type.
To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.