@@ -34,620 +34,620 @@ |
||
34 | 34 | */ |
35 | 35 | trait Converter |
36 | 36 | { |
37 | - /** |
|
38 | - * Format to use for __toString method when type juggling occurs. |
|
39 | - * |
|
40 | - * @var string|Closure|null |
|
41 | - */ |
|
42 | - protected static $toStringFormat; |
|
43 | - |
|
44 | - /** |
|
45 | - * Reset the format used to the default when type juggling a Carbon instance to a string |
|
46 | - * |
|
47 | - * @return void |
|
48 | - */ |
|
49 | - public static function resetToStringFormat() |
|
50 | - { |
|
51 | - static::setToStringFormat(null); |
|
52 | - } |
|
53 | - |
|
54 | - /** |
|
55 | - * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
56 | - * You should rather let Carbon object being casted to string with DEFAULT_TO_STRING_FORMAT, and |
|
57 | - * use other method or custom format passed to format() method if you need to dump an other string |
|
58 | - * format. |
|
59 | - * |
|
60 | - * Set the default format used when type juggling a Carbon instance to a string |
|
61 | - * |
|
62 | - * @param string|Closure|null $format |
|
63 | - * |
|
64 | - * @return void |
|
65 | - */ |
|
66 | - public static function setToStringFormat($format) |
|
67 | - { |
|
68 | - static::$toStringFormat = $format; |
|
69 | - } |
|
70 | - |
|
71 | - /** |
|
72 | - * Returns the formatted date string on success or FALSE on failure. |
|
73 | - * |
|
74 | - * @see https://php.net/manual/en/datetime.format.php |
|
75 | - * |
|
76 | - * @param string $format |
|
77 | - * |
|
78 | - * @return string |
|
79 | - */ |
|
80 | - #[ReturnTypeWillChange] |
|
81 | - public function format($format) |
|
82 | - { |
|
83 | - $function = $this->localFormatFunction ?: static::$formatFunction; |
|
84 | - |
|
85 | - if (!$function) { |
|
86 | - return $this->rawFormat($format); |
|
87 | - } |
|
88 | - |
|
89 | - if (\is_string($function) && method_exists($this, $function)) { |
|
90 | - $function = [$this, $function]; |
|
91 | - } |
|
92 | - |
|
93 | - return $function(...\func_get_args()); |
|
94 | - } |
|
95 | - |
|
96 | - /** |
|
97 | - * @see https://php.net/manual/en/datetime.format.php |
|
98 | - * |
|
99 | - * @param string $format |
|
100 | - * |
|
101 | - * @return string |
|
102 | - */ |
|
103 | - public function rawFormat($format) |
|
104 | - { |
|
105 | - return parent::format($format); |
|
106 | - } |
|
107 | - |
|
108 | - /** |
|
109 | - * Format the instance as a string using the set format |
|
110 | - * |
|
111 | - * @example |
|
112 | - * ``` |
|
113 | - * echo Carbon::now(); // Carbon instances can be casted to string |
|
114 | - * ``` |
|
115 | - * |
|
116 | - * @return string |
|
117 | - */ |
|
118 | - public function __toString() |
|
119 | - { |
|
120 | - $format = $this->localToStringFormat ?? static::$toStringFormat; |
|
121 | - |
|
122 | - return $format instanceof Closure |
|
123 | - ? $format($this) |
|
124 | - : $this->rawFormat($format ?: ( |
|
125 | - \defined('static::DEFAULT_TO_STRING_FORMAT') |
|
126 | - ? static::DEFAULT_TO_STRING_FORMAT |
|
127 | - : CarbonInterface::DEFAULT_TO_STRING_FORMAT |
|
128 | - )); |
|
129 | - } |
|
130 | - |
|
131 | - /** |
|
132 | - * Format the instance as date |
|
133 | - * |
|
134 | - * @example |
|
135 | - * ``` |
|
136 | - * echo Carbon::now()->toDateString(); |
|
137 | - * ``` |
|
138 | - * |
|
139 | - * @return string |
|
140 | - */ |
|
141 | - public function toDateString() |
|
142 | - { |
|
143 | - return $this->rawFormat('Y-m-d'); |
|
144 | - } |
|
145 | - |
|
146 | - /** |
|
147 | - * Format the instance as a readable date |
|
148 | - * |
|
149 | - * @example |
|
150 | - * ``` |
|
151 | - * echo Carbon::now()->toFormattedDateString(); |
|
152 | - * ``` |
|
153 | - * |
|
154 | - * @return string |
|
155 | - */ |
|
156 | - public function toFormattedDateString() |
|
157 | - { |
|
158 | - return $this->rawFormat('M j, Y'); |
|
159 | - } |
|
160 | - |
|
161 | - /** |
|
162 | - * Format the instance as time |
|
163 | - * |
|
164 | - * @example |
|
165 | - * ``` |
|
166 | - * echo Carbon::now()->toTimeString(); |
|
167 | - * ``` |
|
168 | - * |
|
169 | - * @param string $unitPrecision |
|
170 | - * |
|
171 | - * @return string |
|
172 | - */ |
|
173 | - public function toTimeString($unitPrecision = 'second') |
|
174 | - { |
|
175 | - return $this->rawFormat(static::getTimeFormatByPrecision($unitPrecision)); |
|
176 | - } |
|
177 | - |
|
178 | - /** |
|
179 | - * Format the instance as date and time |
|
180 | - * |
|
181 | - * @example |
|
182 | - * ``` |
|
183 | - * echo Carbon::now()->toDateTimeString(); |
|
184 | - * ``` |
|
185 | - * |
|
186 | - * @param string $unitPrecision |
|
187 | - * |
|
188 | - * @return string |
|
189 | - */ |
|
190 | - public function toDateTimeString($unitPrecision = 'second') |
|
191 | - { |
|
192 | - return $this->rawFormat('Y-m-d '.static::getTimeFormatByPrecision($unitPrecision)); |
|
193 | - } |
|
194 | - |
|
195 | - /** |
|
196 | - * Return a format from H:i to H:i:s.u according to given unit precision. |
|
197 | - * |
|
198 | - * @param string $unitPrecision "minute", "second", "millisecond" or "microsecond" |
|
199 | - * |
|
200 | - * @return string |
|
201 | - */ |
|
202 | - public static function getTimeFormatByPrecision($unitPrecision) |
|
203 | - { |
|
204 | - switch (static::singularUnit($unitPrecision)) { |
|
205 | - case 'minute': |
|
206 | - return 'H:i'; |
|
207 | - case 'second': |
|
208 | - return 'H:i:s'; |
|
209 | - case 'm': |
|
210 | - case 'millisecond': |
|
211 | - return 'H:i:s.v'; |
|
212 | - case 'µ': |
|
213 | - case 'microsecond': |
|
214 | - return 'H:i:s.u'; |
|
215 | - } |
|
216 | - |
|
217 | - throw new UnitException('Precision unit expected among: minute, second, millisecond and microsecond.'); |
|
218 | - } |
|
219 | - |
|
220 | - /** |
|
221 | - * Format the instance as date and time T-separated with no timezone |
|
222 | - * |
|
223 | - * @example |
|
224 | - * ``` |
|
225 | - * echo Carbon::now()->toDateTimeLocalString(); |
|
226 | - * echo "\n"; |
|
227 | - * echo Carbon::now()->toDateTimeLocalString('minute'); // You can specify precision among: minute, second, millisecond and microsecond |
|
228 | - * ``` |
|
229 | - * |
|
230 | - * @param string $unitPrecision |
|
231 | - * |
|
232 | - * @return string |
|
233 | - */ |
|
234 | - public function toDateTimeLocalString($unitPrecision = 'second') |
|
235 | - { |
|
236 | - return $this->rawFormat('Y-m-d\T'.static::getTimeFormatByPrecision($unitPrecision)); |
|
237 | - } |
|
238 | - |
|
239 | - /** |
|
240 | - * Format the instance with day, date and time |
|
241 | - * |
|
242 | - * @example |
|
243 | - * ``` |
|
244 | - * echo Carbon::now()->toDayDateTimeString(); |
|
245 | - * ``` |
|
246 | - * |
|
247 | - * @return string |
|
248 | - */ |
|
249 | - public function toDayDateTimeString() |
|
250 | - { |
|
251 | - return $this->rawFormat('D, M j, Y g:i A'); |
|
252 | - } |
|
253 | - |
|
254 | - /** |
|
255 | - * Format the instance as ATOM |
|
256 | - * |
|
257 | - * @example |
|
258 | - * ``` |
|
259 | - * echo Carbon::now()->toAtomString(); |
|
260 | - * ``` |
|
261 | - * |
|
262 | - * @return string |
|
263 | - */ |
|
264 | - public function toAtomString() |
|
265 | - { |
|
266 | - return $this->rawFormat(DateTime::ATOM); |
|
267 | - } |
|
268 | - |
|
269 | - /** |
|
270 | - * Format the instance as COOKIE |
|
271 | - * |
|
272 | - * @example |
|
273 | - * ``` |
|
274 | - * echo Carbon::now()->toCookieString(); |
|
275 | - * ``` |
|
276 | - * |
|
277 | - * @return string |
|
278 | - */ |
|
279 | - public function toCookieString() |
|
280 | - { |
|
281 | - return $this->rawFormat(DateTime::COOKIE); |
|
282 | - } |
|
283 | - |
|
284 | - /** |
|
285 | - * Format the instance as ISO8601 |
|
286 | - * |
|
287 | - * @example |
|
288 | - * ``` |
|
289 | - * echo Carbon::now()->toIso8601String(); |
|
290 | - * ``` |
|
291 | - * |
|
292 | - * @return string |
|
293 | - */ |
|
294 | - public function toIso8601String() |
|
295 | - { |
|
296 | - return $this->toAtomString(); |
|
297 | - } |
|
298 | - |
|
299 | - /** |
|
300 | - * Format the instance as RFC822 |
|
301 | - * |
|
302 | - * @example |
|
303 | - * ``` |
|
304 | - * echo Carbon::now()->toRfc822String(); |
|
305 | - * ``` |
|
306 | - * |
|
307 | - * @return string |
|
308 | - */ |
|
309 | - public function toRfc822String() |
|
310 | - { |
|
311 | - return $this->rawFormat(DateTime::RFC822); |
|
312 | - } |
|
313 | - |
|
314 | - /** |
|
315 | - * Convert the instance to UTC and return as Zulu ISO8601 |
|
316 | - * |
|
317 | - * @example |
|
318 | - * ``` |
|
319 | - * echo Carbon::now()->toIso8601ZuluString(); |
|
320 | - * ``` |
|
321 | - * |
|
322 | - * @param string $unitPrecision |
|
323 | - * |
|
324 | - * @return string |
|
325 | - */ |
|
326 | - public function toIso8601ZuluString($unitPrecision = 'second') |
|
327 | - { |
|
328 | - return $this->avoidMutation() |
|
329 | - ->utc() |
|
330 | - ->rawFormat('Y-m-d\T'.static::getTimeFormatByPrecision($unitPrecision).'\Z'); |
|
331 | - } |
|
332 | - |
|
333 | - /** |
|
334 | - * Format the instance as RFC850 |
|
335 | - * |
|
336 | - * @example |
|
337 | - * ``` |
|
338 | - * echo Carbon::now()->toRfc850String(); |
|
339 | - * ``` |
|
340 | - * |
|
341 | - * @return string |
|
342 | - */ |
|
343 | - public function toRfc850String() |
|
344 | - { |
|
345 | - return $this->rawFormat(DateTime::RFC850); |
|
346 | - } |
|
347 | - |
|
348 | - /** |
|
349 | - * Format the instance as RFC1036 |
|
350 | - * |
|
351 | - * @example |
|
352 | - * ``` |
|
353 | - * echo Carbon::now()->toRfc1036String(); |
|
354 | - * ``` |
|
355 | - * |
|
356 | - * @return string |
|
357 | - */ |
|
358 | - public function toRfc1036String() |
|
359 | - { |
|
360 | - return $this->rawFormat(DateTime::RFC1036); |
|
361 | - } |
|
362 | - |
|
363 | - /** |
|
364 | - * Format the instance as RFC1123 |
|
365 | - * |
|
366 | - * @example |
|
367 | - * ``` |
|
368 | - * echo Carbon::now()->toRfc1123String(); |
|
369 | - * ``` |
|
370 | - * |
|
371 | - * @return string |
|
372 | - */ |
|
373 | - public function toRfc1123String() |
|
374 | - { |
|
375 | - return $this->rawFormat(DateTime::RFC1123); |
|
376 | - } |
|
377 | - |
|
378 | - /** |
|
379 | - * Format the instance as RFC2822 |
|
380 | - * |
|
381 | - * @example |
|
382 | - * ``` |
|
383 | - * echo Carbon::now()->toRfc2822String(); |
|
384 | - * ``` |
|
385 | - * |
|
386 | - * @return string |
|
387 | - */ |
|
388 | - public function toRfc2822String() |
|
389 | - { |
|
390 | - return $this->rawFormat(DateTime::RFC2822); |
|
391 | - } |
|
392 | - |
|
393 | - /** |
|
394 | - * Format the instance as RFC3339 |
|
395 | - * |
|
396 | - * @param bool $extended |
|
397 | - * |
|
398 | - * @example |
|
399 | - * ``` |
|
400 | - * echo Carbon::now()->toRfc3339String() . "\n"; |
|
401 | - * echo Carbon::now()->toRfc3339String(true) . "\n"; |
|
402 | - * ``` |
|
403 | - * |
|
404 | - * @return string |
|
405 | - */ |
|
406 | - public function toRfc3339String($extended = false) |
|
407 | - { |
|
408 | - $format = DateTime::RFC3339; |
|
409 | - if ($extended) { |
|
410 | - $format = DateTime::RFC3339_EXTENDED; |
|
411 | - } |
|
412 | - |
|
413 | - return $this->rawFormat($format); |
|
414 | - } |
|
415 | - |
|
416 | - /** |
|
417 | - * Format the instance as RSS |
|
418 | - * |
|
419 | - * @example |
|
420 | - * ``` |
|
421 | - * echo Carbon::now()->toRssString(); |
|
422 | - * ``` |
|
423 | - * |
|
424 | - * @return string |
|
425 | - */ |
|
426 | - public function toRssString() |
|
427 | - { |
|
428 | - return $this->rawFormat(DateTime::RSS); |
|
429 | - } |
|
430 | - |
|
431 | - /** |
|
432 | - * Format the instance as W3C |
|
433 | - * |
|
434 | - * @example |
|
435 | - * ``` |
|
436 | - * echo Carbon::now()->toW3cString(); |
|
437 | - * ``` |
|
438 | - * |
|
439 | - * @return string |
|
440 | - */ |
|
441 | - public function toW3cString() |
|
442 | - { |
|
443 | - return $this->rawFormat(DateTime::W3C); |
|
444 | - } |
|
445 | - |
|
446 | - /** |
|
447 | - * Format the instance as RFC7231 |
|
448 | - * |
|
449 | - * @example |
|
450 | - * ``` |
|
451 | - * echo Carbon::now()->toRfc7231String(); |
|
452 | - * ``` |
|
453 | - * |
|
454 | - * @return string |
|
455 | - */ |
|
456 | - public function toRfc7231String() |
|
457 | - { |
|
458 | - return $this->avoidMutation() |
|
459 | - ->setTimezone('GMT') |
|
460 | - ->rawFormat(\defined('static::RFC7231_FORMAT') ? static::RFC7231_FORMAT : CarbonInterface::RFC7231_FORMAT); |
|
461 | - } |
|
462 | - |
|
463 | - /** |
|
464 | - * Get default array representation. |
|
465 | - * |
|
466 | - * @example |
|
467 | - * ``` |
|
468 | - * var_dump(Carbon::now()->toArray()); |
|
469 | - * ``` |
|
470 | - * |
|
471 | - * @return array |
|
472 | - */ |
|
473 | - public function toArray() |
|
474 | - { |
|
475 | - return [ |
|
476 | - 'year' => $this->year, |
|
477 | - 'month' => $this->month, |
|
478 | - 'day' => $this->day, |
|
479 | - 'dayOfWeek' => $this->dayOfWeek, |
|
480 | - 'dayOfYear' => $this->dayOfYear, |
|
481 | - 'hour' => $this->hour, |
|
482 | - 'minute' => $this->minute, |
|
483 | - 'second' => $this->second, |
|
484 | - 'micro' => $this->micro, |
|
485 | - 'timestamp' => $this->timestamp, |
|
486 | - 'formatted' => $this->rawFormat(\defined('static::DEFAULT_TO_STRING_FORMAT') ? static::DEFAULT_TO_STRING_FORMAT : CarbonInterface::DEFAULT_TO_STRING_FORMAT), |
|
487 | - 'timezone' => $this->timezone, |
|
488 | - ]; |
|
489 | - } |
|
490 | - |
|
491 | - /** |
|
492 | - * Get default object representation. |
|
493 | - * |
|
494 | - * @example |
|
495 | - * ``` |
|
496 | - * var_dump(Carbon::now()->toObject()); |
|
497 | - * ``` |
|
498 | - * |
|
499 | - * @return object |
|
500 | - */ |
|
501 | - public function toObject() |
|
502 | - { |
|
503 | - return (object) $this->toArray(); |
|
504 | - } |
|
505 | - |
|
506 | - /** |
|
507 | - * Returns english human readable complete date string. |
|
508 | - * |
|
509 | - * @example |
|
510 | - * ``` |
|
511 | - * echo Carbon::now()->toString(); |
|
512 | - * ``` |
|
513 | - * |
|
514 | - * @return string |
|
515 | - */ |
|
516 | - public function toString() |
|
517 | - { |
|
518 | - return $this->avoidMutation()->locale('en')->isoFormat('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); |
|
519 | - } |
|
520 | - |
|
521 | - /** |
|
522 | - * Return the ISO-8601 string (ex: 1977-04-22T06:00:00Z, if $keepOffset truthy, offset will be kept: |
|
523 | - * 1977-04-22T01:00:00-05:00). |
|
524 | - * |
|
525 | - * @example |
|
526 | - * ``` |
|
527 | - * echo Carbon::now('America/Toronto')->toISOString() . "\n"; |
|
528 | - * echo Carbon::now('America/Toronto')->toISOString(true) . "\n"; |
|
529 | - * ``` |
|
530 | - * |
|
531 | - * @param bool $keepOffset Pass true to keep the date offset. Else forced to UTC. |
|
532 | - * |
|
533 | - * @return null|string |
|
534 | - */ |
|
535 | - public function toISOString($keepOffset = false) |
|
536 | - { |
|
537 | - if (!$this->isValid()) { |
|
538 | - return null; |
|
539 | - } |
|
540 | - |
|
541 | - $yearFormat = $this->year < 0 || $this->year > 9999 ? 'YYYYYY' : 'YYYY'; |
|
542 | - $tzFormat = $keepOffset ? 'Z' : '[Z]'; |
|
543 | - $date = $keepOffset ? $this : $this->avoidMutation()->utc(); |
|
544 | - |
|
545 | - return $date->isoFormat("$yearFormat-MM-DD[T]HH:mm:ss.SSSSSS$tzFormat"); |
|
546 | - } |
|
547 | - |
|
548 | - /** |
|
549 | - * Return the ISO-8601 string (ex: 1977-04-22T06:00:00Z) with UTC timezone. |
|
550 | - * |
|
551 | - * @example |
|
552 | - * ``` |
|
553 | - * echo Carbon::now('America/Toronto')->toJSON(); |
|
554 | - * ``` |
|
555 | - * |
|
556 | - * @return null|string |
|
557 | - */ |
|
558 | - public function toJSON() |
|
559 | - { |
|
560 | - return $this->toISOString(); |
|
561 | - } |
|
562 | - |
|
563 | - /** |
|
564 | - * Return native DateTime PHP object matching the current instance. |
|
565 | - * |
|
566 | - * @example |
|
567 | - * ``` |
|
568 | - * var_dump(Carbon::now()->toDateTime()); |
|
569 | - * ``` |
|
570 | - * |
|
571 | - * @return DateTime |
|
572 | - */ |
|
573 | - public function toDateTime() |
|
574 | - { |
|
575 | - return new DateTime($this->rawFormat('Y-m-d H:i:s.u'), $this->getTimezone()); |
|
576 | - } |
|
577 | - |
|
578 | - /** |
|
579 | - * Return native toDateTimeImmutable PHP object matching the current instance. |
|
580 | - * |
|
581 | - * @example |
|
582 | - * ``` |
|
583 | - * var_dump(Carbon::now()->toDateTimeImmutable()); |
|
584 | - * ``` |
|
585 | - * |
|
586 | - * @return DateTimeImmutable |
|
587 | - */ |
|
588 | - public function toDateTimeImmutable() |
|
589 | - { |
|
590 | - return new DateTimeImmutable($this->rawFormat('Y-m-d H:i:s.u'), $this->getTimezone()); |
|
591 | - } |
|
592 | - |
|
593 | - /** |
|
594 | - * @alias toDateTime |
|
595 | - * |
|
596 | - * Return native DateTime PHP object matching the current instance. |
|
597 | - * |
|
598 | - * @example |
|
599 | - * ``` |
|
600 | - * var_dump(Carbon::now()->toDate()); |
|
601 | - * ``` |
|
602 | - * |
|
603 | - * @return DateTime |
|
604 | - */ |
|
605 | - public function toDate() |
|
606 | - { |
|
607 | - return $this->toDateTime(); |
|
608 | - } |
|
609 | - |
|
610 | - /** |
|
611 | - * Create a iterable CarbonPeriod object from current date to a given end date (and optional interval). |
|
612 | - * |
|
613 | - * @param \DateTimeInterface|Carbon|CarbonImmutable|int|null $end period end date or recurrences count if int |
|
614 | - * @param int|\DateInterval|string|null $interval period default interval or number of the given $unit |
|
615 | - * @param string|null $unit if specified, $interval must be an integer |
|
616 | - * |
|
617 | - * @return CarbonPeriod |
|
618 | - */ |
|
619 | - public function toPeriod($end = null, $interval = null, $unit = null) |
|
620 | - { |
|
621 | - if ($unit) { |
|
622 | - $interval = CarbonInterval::make("$interval ".static::pluralUnit($unit)); |
|
623 | - } |
|
624 | - |
|
625 | - $period = (new CarbonPeriod())->setDateClass(static::class)->setStartDate($this); |
|
626 | - |
|
627 | - if ($interval) { |
|
628 | - $period->setDateInterval($interval); |
|
629 | - } |
|
630 | - |
|
631 | - if (\is_int($end) || (\is_string($end) && ctype_digit($end))) { |
|
632 | - $period->setRecurrences($end); |
|
633 | - } elseif ($end) { |
|
634 | - $period->setEndDate($end); |
|
635 | - } |
|
636 | - |
|
637 | - return $period; |
|
638 | - } |
|
639 | - |
|
640 | - /** |
|
641 | - * Create a iterable CarbonPeriod object from current date to a given end date (and optional interval). |
|
642 | - * |
|
643 | - * @param \DateTimeInterface|Carbon|CarbonImmutable|null $end period end date |
|
644 | - * @param int|\DateInterval|string|null $interval period default interval or number of the given $unit |
|
645 | - * @param string|null $unit if specified, $interval must be an integer |
|
646 | - * |
|
647 | - * @return CarbonPeriod |
|
648 | - */ |
|
649 | - public function range($end = null, $interval = null, $unit = null) |
|
650 | - { |
|
651 | - return $this->toPeriod($end, $interval, $unit); |
|
652 | - } |
|
37 | + /** |
|
38 | + * Format to use for __toString method when type juggling occurs. |
|
39 | + * |
|
40 | + * @var string|Closure|null |
|
41 | + */ |
|
42 | + protected static $toStringFormat; |
|
43 | + |
|
44 | + /** |
|
45 | + * Reset the format used to the default when type juggling a Carbon instance to a string |
|
46 | + * |
|
47 | + * @return void |
|
48 | + */ |
|
49 | + public static function resetToStringFormat() |
|
50 | + { |
|
51 | + static::setToStringFormat(null); |
|
52 | + } |
|
53 | + |
|
54 | + /** |
|
55 | + * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
56 | + * You should rather let Carbon object being casted to string with DEFAULT_TO_STRING_FORMAT, and |
|
57 | + * use other method or custom format passed to format() method if you need to dump an other string |
|
58 | + * format. |
|
59 | + * |
|
60 | + * Set the default format used when type juggling a Carbon instance to a string |
|
61 | + * |
|
62 | + * @param string|Closure|null $format |
|
63 | + * |
|
64 | + * @return void |
|
65 | + */ |
|
66 | + public static function setToStringFormat($format) |
|
67 | + { |
|
68 | + static::$toStringFormat = $format; |
|
69 | + } |
|
70 | + |
|
71 | + /** |
|
72 | + * Returns the formatted date string on success or FALSE on failure. |
|
73 | + * |
|
74 | + * @see https://php.net/manual/en/datetime.format.php |
|
75 | + * |
|
76 | + * @param string $format |
|
77 | + * |
|
78 | + * @return string |
|
79 | + */ |
|
80 | + #[ReturnTypeWillChange] |
|
81 | + public function format($format) |
|
82 | + { |
|
83 | + $function = $this->localFormatFunction ?: static::$formatFunction; |
|
84 | + |
|
85 | + if (!$function) { |
|
86 | + return $this->rawFormat($format); |
|
87 | + } |
|
88 | + |
|
89 | + if (\is_string($function) && method_exists($this, $function)) { |
|
90 | + $function = [$this, $function]; |
|
91 | + } |
|
92 | + |
|
93 | + return $function(...\func_get_args()); |
|
94 | + } |
|
95 | + |
|
96 | + /** |
|
97 | + * @see https://php.net/manual/en/datetime.format.php |
|
98 | + * |
|
99 | + * @param string $format |
|
100 | + * |
|
101 | + * @return string |
|
102 | + */ |
|
103 | + public function rawFormat($format) |
|
104 | + { |
|
105 | + return parent::format($format); |
|
106 | + } |
|
107 | + |
|
108 | + /** |
|
109 | + * Format the instance as a string using the set format |
|
110 | + * |
|
111 | + * @example |
|
112 | + * ``` |
|
113 | + * echo Carbon::now(); // Carbon instances can be casted to string |
|
114 | + * ``` |
|
115 | + * |
|
116 | + * @return string |
|
117 | + */ |
|
118 | + public function __toString() |
|
119 | + { |
|
120 | + $format = $this->localToStringFormat ?? static::$toStringFormat; |
|
121 | + |
|
122 | + return $format instanceof Closure |
|
123 | + ? $format($this) |
|
124 | + : $this->rawFormat($format ?: ( |
|
125 | + \defined('static::DEFAULT_TO_STRING_FORMAT') |
|
126 | + ? static::DEFAULT_TO_STRING_FORMAT |
|
127 | + : CarbonInterface::DEFAULT_TO_STRING_FORMAT |
|
128 | + )); |
|
129 | + } |
|
130 | + |
|
131 | + /** |
|
132 | + * Format the instance as date |
|
133 | + * |
|
134 | + * @example |
|
135 | + * ``` |
|
136 | + * echo Carbon::now()->toDateString(); |
|
137 | + * ``` |
|
138 | + * |
|
139 | + * @return string |
|
140 | + */ |
|
141 | + public function toDateString() |
|
142 | + { |
|
143 | + return $this->rawFormat('Y-m-d'); |
|
144 | + } |
|
145 | + |
|
146 | + /** |
|
147 | + * Format the instance as a readable date |
|
148 | + * |
|
149 | + * @example |
|
150 | + * ``` |
|
151 | + * echo Carbon::now()->toFormattedDateString(); |
|
152 | + * ``` |
|
153 | + * |
|
154 | + * @return string |
|
155 | + */ |
|
156 | + public function toFormattedDateString() |
|
157 | + { |
|
158 | + return $this->rawFormat('M j, Y'); |
|
159 | + } |
|
160 | + |
|
161 | + /** |
|
162 | + * Format the instance as time |
|
163 | + * |
|
164 | + * @example |
|
165 | + * ``` |
|
166 | + * echo Carbon::now()->toTimeString(); |
|
167 | + * ``` |
|
168 | + * |
|
169 | + * @param string $unitPrecision |
|
170 | + * |
|
171 | + * @return string |
|
172 | + */ |
|
173 | + public function toTimeString($unitPrecision = 'second') |
|
174 | + { |
|
175 | + return $this->rawFormat(static::getTimeFormatByPrecision($unitPrecision)); |
|
176 | + } |
|
177 | + |
|
178 | + /** |
|
179 | + * Format the instance as date and time |
|
180 | + * |
|
181 | + * @example |
|
182 | + * ``` |
|
183 | + * echo Carbon::now()->toDateTimeString(); |
|
184 | + * ``` |
|
185 | + * |
|
186 | + * @param string $unitPrecision |
|
187 | + * |
|
188 | + * @return string |
|
189 | + */ |
|
190 | + public function toDateTimeString($unitPrecision = 'second') |
|
191 | + { |
|
192 | + return $this->rawFormat('Y-m-d '.static::getTimeFormatByPrecision($unitPrecision)); |
|
193 | + } |
|
194 | + |
|
195 | + /** |
|
196 | + * Return a format from H:i to H:i:s.u according to given unit precision. |
|
197 | + * |
|
198 | + * @param string $unitPrecision "minute", "second", "millisecond" or "microsecond" |
|
199 | + * |
|
200 | + * @return string |
|
201 | + */ |
|
202 | + public static function getTimeFormatByPrecision($unitPrecision) |
|
203 | + { |
|
204 | + switch (static::singularUnit($unitPrecision)) { |
|
205 | + case 'minute': |
|
206 | + return 'H:i'; |
|
207 | + case 'second': |
|
208 | + return 'H:i:s'; |
|
209 | + case 'm': |
|
210 | + case 'millisecond': |
|
211 | + return 'H:i:s.v'; |
|
212 | + case 'µ': |
|
213 | + case 'microsecond': |
|
214 | + return 'H:i:s.u'; |
|
215 | + } |
|
216 | + |
|
217 | + throw new UnitException('Precision unit expected among: minute, second, millisecond and microsecond.'); |
|
218 | + } |
|
219 | + |
|
220 | + /** |
|
221 | + * Format the instance as date and time T-separated with no timezone |
|
222 | + * |
|
223 | + * @example |
|
224 | + * ``` |
|
225 | + * echo Carbon::now()->toDateTimeLocalString(); |
|
226 | + * echo "\n"; |
|
227 | + * echo Carbon::now()->toDateTimeLocalString('minute'); // You can specify precision among: minute, second, millisecond and microsecond |
|
228 | + * ``` |
|
229 | + * |
|
230 | + * @param string $unitPrecision |
|
231 | + * |
|
232 | + * @return string |
|
233 | + */ |
|
234 | + public function toDateTimeLocalString($unitPrecision = 'second') |
|
235 | + { |
|
236 | + return $this->rawFormat('Y-m-d\T'.static::getTimeFormatByPrecision($unitPrecision)); |
|
237 | + } |
|
238 | + |
|
239 | + /** |
|
240 | + * Format the instance with day, date and time |
|
241 | + * |
|
242 | + * @example |
|
243 | + * ``` |
|
244 | + * echo Carbon::now()->toDayDateTimeString(); |
|
245 | + * ``` |
|
246 | + * |
|
247 | + * @return string |
|
248 | + */ |
|
249 | + public function toDayDateTimeString() |
|
250 | + { |
|
251 | + return $this->rawFormat('D, M j, Y g:i A'); |
|
252 | + } |
|
253 | + |
|
254 | + /** |
|
255 | + * Format the instance as ATOM |
|
256 | + * |
|
257 | + * @example |
|
258 | + * ``` |
|
259 | + * echo Carbon::now()->toAtomString(); |
|
260 | + * ``` |
|
261 | + * |
|
262 | + * @return string |
|
263 | + */ |
|
264 | + public function toAtomString() |
|
265 | + { |
|
266 | + return $this->rawFormat(DateTime::ATOM); |
|
267 | + } |
|
268 | + |
|
269 | + /** |
|
270 | + * Format the instance as COOKIE |
|
271 | + * |
|
272 | + * @example |
|
273 | + * ``` |
|
274 | + * echo Carbon::now()->toCookieString(); |
|
275 | + * ``` |
|
276 | + * |
|
277 | + * @return string |
|
278 | + */ |
|
279 | + public function toCookieString() |
|
280 | + { |
|
281 | + return $this->rawFormat(DateTime::COOKIE); |
|
282 | + } |
|
283 | + |
|
284 | + /** |
|
285 | + * Format the instance as ISO8601 |
|
286 | + * |
|
287 | + * @example |
|
288 | + * ``` |
|
289 | + * echo Carbon::now()->toIso8601String(); |
|
290 | + * ``` |
|
291 | + * |
|
292 | + * @return string |
|
293 | + */ |
|
294 | + public function toIso8601String() |
|
295 | + { |
|
296 | + return $this->toAtomString(); |
|
297 | + } |
|
298 | + |
|
299 | + /** |
|
300 | + * Format the instance as RFC822 |
|
301 | + * |
|
302 | + * @example |
|
303 | + * ``` |
|
304 | + * echo Carbon::now()->toRfc822String(); |
|
305 | + * ``` |
|
306 | + * |
|
307 | + * @return string |
|
308 | + */ |
|
309 | + public function toRfc822String() |
|
310 | + { |
|
311 | + return $this->rawFormat(DateTime::RFC822); |
|
312 | + } |
|
313 | + |
|
314 | + /** |
|
315 | + * Convert the instance to UTC and return as Zulu ISO8601 |
|
316 | + * |
|
317 | + * @example |
|
318 | + * ``` |
|
319 | + * echo Carbon::now()->toIso8601ZuluString(); |
|
320 | + * ``` |
|
321 | + * |
|
322 | + * @param string $unitPrecision |
|
323 | + * |
|
324 | + * @return string |
|
325 | + */ |
|
326 | + public function toIso8601ZuluString($unitPrecision = 'second') |
|
327 | + { |
|
328 | + return $this->avoidMutation() |
|
329 | + ->utc() |
|
330 | + ->rawFormat('Y-m-d\T'.static::getTimeFormatByPrecision($unitPrecision).'\Z'); |
|
331 | + } |
|
332 | + |
|
333 | + /** |
|
334 | + * Format the instance as RFC850 |
|
335 | + * |
|
336 | + * @example |
|
337 | + * ``` |
|
338 | + * echo Carbon::now()->toRfc850String(); |
|
339 | + * ``` |
|
340 | + * |
|
341 | + * @return string |
|
342 | + */ |
|
343 | + public function toRfc850String() |
|
344 | + { |
|
345 | + return $this->rawFormat(DateTime::RFC850); |
|
346 | + } |
|
347 | + |
|
348 | + /** |
|
349 | + * Format the instance as RFC1036 |
|
350 | + * |
|
351 | + * @example |
|
352 | + * ``` |
|
353 | + * echo Carbon::now()->toRfc1036String(); |
|
354 | + * ``` |
|
355 | + * |
|
356 | + * @return string |
|
357 | + */ |
|
358 | + public function toRfc1036String() |
|
359 | + { |
|
360 | + return $this->rawFormat(DateTime::RFC1036); |
|
361 | + } |
|
362 | + |
|
363 | + /** |
|
364 | + * Format the instance as RFC1123 |
|
365 | + * |
|
366 | + * @example |
|
367 | + * ``` |
|
368 | + * echo Carbon::now()->toRfc1123String(); |
|
369 | + * ``` |
|
370 | + * |
|
371 | + * @return string |
|
372 | + */ |
|
373 | + public function toRfc1123String() |
|
374 | + { |
|
375 | + return $this->rawFormat(DateTime::RFC1123); |
|
376 | + } |
|
377 | + |
|
378 | + /** |
|
379 | + * Format the instance as RFC2822 |
|
380 | + * |
|
381 | + * @example |
|
382 | + * ``` |
|
383 | + * echo Carbon::now()->toRfc2822String(); |
|
384 | + * ``` |
|
385 | + * |
|
386 | + * @return string |
|
387 | + */ |
|
388 | + public function toRfc2822String() |
|
389 | + { |
|
390 | + return $this->rawFormat(DateTime::RFC2822); |
|
391 | + } |
|
392 | + |
|
393 | + /** |
|
394 | + * Format the instance as RFC3339 |
|
395 | + * |
|
396 | + * @param bool $extended |
|
397 | + * |
|
398 | + * @example |
|
399 | + * ``` |
|
400 | + * echo Carbon::now()->toRfc3339String() . "\n"; |
|
401 | + * echo Carbon::now()->toRfc3339String(true) . "\n"; |
|
402 | + * ``` |
|
403 | + * |
|
404 | + * @return string |
|
405 | + */ |
|
406 | + public function toRfc3339String($extended = false) |
|
407 | + { |
|
408 | + $format = DateTime::RFC3339; |
|
409 | + if ($extended) { |
|
410 | + $format = DateTime::RFC3339_EXTENDED; |
|
411 | + } |
|
412 | + |
|
413 | + return $this->rawFormat($format); |
|
414 | + } |
|
415 | + |
|
416 | + /** |
|
417 | + * Format the instance as RSS |
|
418 | + * |
|
419 | + * @example |
|
420 | + * ``` |
|
421 | + * echo Carbon::now()->toRssString(); |
|
422 | + * ``` |
|
423 | + * |
|
424 | + * @return string |
|
425 | + */ |
|
426 | + public function toRssString() |
|
427 | + { |
|
428 | + return $this->rawFormat(DateTime::RSS); |
|
429 | + } |
|
430 | + |
|
431 | + /** |
|
432 | + * Format the instance as W3C |
|
433 | + * |
|
434 | + * @example |
|
435 | + * ``` |
|
436 | + * echo Carbon::now()->toW3cString(); |
|
437 | + * ``` |
|
438 | + * |
|
439 | + * @return string |
|
440 | + */ |
|
441 | + public function toW3cString() |
|
442 | + { |
|
443 | + return $this->rawFormat(DateTime::W3C); |
|
444 | + } |
|
445 | + |
|
446 | + /** |
|
447 | + * Format the instance as RFC7231 |
|
448 | + * |
|
449 | + * @example |
|
450 | + * ``` |
|
451 | + * echo Carbon::now()->toRfc7231String(); |
|
452 | + * ``` |
|
453 | + * |
|
454 | + * @return string |
|
455 | + */ |
|
456 | + public function toRfc7231String() |
|
457 | + { |
|
458 | + return $this->avoidMutation() |
|
459 | + ->setTimezone('GMT') |
|
460 | + ->rawFormat(\defined('static::RFC7231_FORMAT') ? static::RFC7231_FORMAT : CarbonInterface::RFC7231_FORMAT); |
|
461 | + } |
|
462 | + |
|
463 | + /** |
|
464 | + * Get default array representation. |
|
465 | + * |
|
466 | + * @example |
|
467 | + * ``` |
|
468 | + * var_dump(Carbon::now()->toArray()); |
|
469 | + * ``` |
|
470 | + * |
|
471 | + * @return array |
|
472 | + */ |
|
473 | + public function toArray() |
|
474 | + { |
|
475 | + return [ |
|
476 | + 'year' => $this->year, |
|
477 | + 'month' => $this->month, |
|
478 | + 'day' => $this->day, |
|
479 | + 'dayOfWeek' => $this->dayOfWeek, |
|
480 | + 'dayOfYear' => $this->dayOfYear, |
|
481 | + 'hour' => $this->hour, |
|
482 | + 'minute' => $this->minute, |
|
483 | + 'second' => $this->second, |
|
484 | + 'micro' => $this->micro, |
|
485 | + 'timestamp' => $this->timestamp, |
|
486 | + 'formatted' => $this->rawFormat(\defined('static::DEFAULT_TO_STRING_FORMAT') ? static::DEFAULT_TO_STRING_FORMAT : CarbonInterface::DEFAULT_TO_STRING_FORMAT), |
|
487 | + 'timezone' => $this->timezone, |
|
488 | + ]; |
|
489 | + } |
|
490 | + |
|
491 | + /** |
|
492 | + * Get default object representation. |
|
493 | + * |
|
494 | + * @example |
|
495 | + * ``` |
|
496 | + * var_dump(Carbon::now()->toObject()); |
|
497 | + * ``` |
|
498 | + * |
|
499 | + * @return object |
|
500 | + */ |
|
501 | + public function toObject() |
|
502 | + { |
|
503 | + return (object) $this->toArray(); |
|
504 | + } |
|
505 | + |
|
506 | + /** |
|
507 | + * Returns english human readable complete date string. |
|
508 | + * |
|
509 | + * @example |
|
510 | + * ``` |
|
511 | + * echo Carbon::now()->toString(); |
|
512 | + * ``` |
|
513 | + * |
|
514 | + * @return string |
|
515 | + */ |
|
516 | + public function toString() |
|
517 | + { |
|
518 | + return $this->avoidMutation()->locale('en')->isoFormat('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); |
|
519 | + } |
|
520 | + |
|
521 | + /** |
|
522 | + * Return the ISO-8601 string (ex: 1977-04-22T06:00:00Z, if $keepOffset truthy, offset will be kept: |
|
523 | + * 1977-04-22T01:00:00-05:00). |
|
524 | + * |
|
525 | + * @example |
|
526 | + * ``` |
|
527 | + * echo Carbon::now('America/Toronto')->toISOString() . "\n"; |
|
528 | + * echo Carbon::now('America/Toronto')->toISOString(true) . "\n"; |
|
529 | + * ``` |
|
530 | + * |
|
531 | + * @param bool $keepOffset Pass true to keep the date offset. Else forced to UTC. |
|
532 | + * |
|
533 | + * @return null|string |
|
534 | + */ |
|
535 | + public function toISOString($keepOffset = false) |
|
536 | + { |
|
537 | + if (!$this->isValid()) { |
|
538 | + return null; |
|
539 | + } |
|
540 | + |
|
541 | + $yearFormat = $this->year < 0 || $this->year > 9999 ? 'YYYYYY' : 'YYYY'; |
|
542 | + $tzFormat = $keepOffset ? 'Z' : '[Z]'; |
|
543 | + $date = $keepOffset ? $this : $this->avoidMutation()->utc(); |
|
544 | + |
|
545 | + return $date->isoFormat("$yearFormat-MM-DD[T]HH:mm:ss.SSSSSS$tzFormat"); |
|
546 | + } |
|
547 | + |
|
548 | + /** |
|
549 | + * Return the ISO-8601 string (ex: 1977-04-22T06:00:00Z) with UTC timezone. |
|
550 | + * |
|
551 | + * @example |
|
552 | + * ``` |
|
553 | + * echo Carbon::now('America/Toronto')->toJSON(); |
|
554 | + * ``` |
|
555 | + * |
|
556 | + * @return null|string |
|
557 | + */ |
|
558 | + public function toJSON() |
|
559 | + { |
|
560 | + return $this->toISOString(); |
|
561 | + } |
|
562 | + |
|
563 | + /** |
|
564 | + * Return native DateTime PHP object matching the current instance. |
|
565 | + * |
|
566 | + * @example |
|
567 | + * ``` |
|
568 | + * var_dump(Carbon::now()->toDateTime()); |
|
569 | + * ``` |
|
570 | + * |
|
571 | + * @return DateTime |
|
572 | + */ |
|
573 | + public function toDateTime() |
|
574 | + { |
|
575 | + return new DateTime($this->rawFormat('Y-m-d H:i:s.u'), $this->getTimezone()); |
|
576 | + } |
|
577 | + |
|
578 | + /** |
|
579 | + * Return native toDateTimeImmutable PHP object matching the current instance. |
|
580 | + * |
|
581 | + * @example |
|
582 | + * ``` |
|
583 | + * var_dump(Carbon::now()->toDateTimeImmutable()); |
|
584 | + * ``` |
|
585 | + * |
|
586 | + * @return DateTimeImmutable |
|
587 | + */ |
|
588 | + public function toDateTimeImmutable() |
|
589 | + { |
|
590 | + return new DateTimeImmutable($this->rawFormat('Y-m-d H:i:s.u'), $this->getTimezone()); |
|
591 | + } |
|
592 | + |
|
593 | + /** |
|
594 | + * @alias toDateTime |
|
595 | + * |
|
596 | + * Return native DateTime PHP object matching the current instance. |
|
597 | + * |
|
598 | + * @example |
|
599 | + * ``` |
|
600 | + * var_dump(Carbon::now()->toDate()); |
|
601 | + * ``` |
|
602 | + * |
|
603 | + * @return DateTime |
|
604 | + */ |
|
605 | + public function toDate() |
|
606 | + { |
|
607 | + return $this->toDateTime(); |
|
608 | + } |
|
609 | + |
|
610 | + /** |
|
611 | + * Create a iterable CarbonPeriod object from current date to a given end date (and optional interval). |
|
612 | + * |
|
613 | + * @param \DateTimeInterface|Carbon|CarbonImmutable|int|null $end period end date or recurrences count if int |
|
614 | + * @param int|\DateInterval|string|null $interval period default interval or number of the given $unit |
|
615 | + * @param string|null $unit if specified, $interval must be an integer |
|
616 | + * |
|
617 | + * @return CarbonPeriod |
|
618 | + */ |
|
619 | + public function toPeriod($end = null, $interval = null, $unit = null) |
|
620 | + { |
|
621 | + if ($unit) { |
|
622 | + $interval = CarbonInterval::make("$interval ".static::pluralUnit($unit)); |
|
623 | + } |
|
624 | + |
|
625 | + $period = (new CarbonPeriod())->setDateClass(static::class)->setStartDate($this); |
|
626 | + |
|
627 | + if ($interval) { |
|
628 | + $period->setDateInterval($interval); |
|
629 | + } |
|
630 | + |
|
631 | + if (\is_int($end) || (\is_string($end) && ctype_digit($end))) { |
|
632 | + $period->setRecurrences($end); |
|
633 | + } elseif ($end) { |
|
634 | + $period->setEndDate($end); |
|
635 | + } |
|
636 | + |
|
637 | + return $period; |
|
638 | + } |
|
639 | + |
|
640 | + /** |
|
641 | + * Create a iterable CarbonPeriod object from current date to a given end date (and optional interval). |
|
642 | + * |
|
643 | + * @param \DateTimeInterface|Carbon|CarbonImmutable|null $end period end date |
|
644 | + * @param int|\DateInterval|string|null $interval period default interval or number of the given $unit |
|
645 | + * @param string|null $unit if specified, $interval must be an integer |
|
646 | + * |
|
647 | + * @return CarbonPeriod |
|
648 | + */ |
|
649 | + public function range($end = null, $interval = null, $unit = null) |
|
650 | + { |
|
651 | + return $this->toPeriod($end, $interval, $unit); |
|
652 | + } |
|
653 | 653 | } |
@@ -15,47 +15,47 @@ |
||
15 | 15 | |
16 | 16 | trait DeprecatedProperties |
17 | 17 | { |
18 | - /** |
|
19 | - * the day of week in current locale LC_TIME |
|
20 | - * |
|
21 | - * @var string |
|
22 | - * |
|
23 | - * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
24 | - * Use ->isoFormat('MMM') instead. |
|
25 | - * Deprecated since 2.55.0 |
|
26 | - */ |
|
27 | - public $localeDayOfWeek; |
|
18 | + /** |
|
19 | + * the day of week in current locale LC_TIME |
|
20 | + * |
|
21 | + * @var string |
|
22 | + * |
|
23 | + * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
24 | + * Use ->isoFormat('MMM') instead. |
|
25 | + * Deprecated since 2.55.0 |
|
26 | + */ |
|
27 | + public $localeDayOfWeek; |
|
28 | 28 | |
29 | - /** |
|
30 | - * the abbreviated day of week in current locale LC_TIME |
|
31 | - * |
|
32 | - * @var string |
|
33 | - * |
|
34 | - * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
35 | - * Use ->isoFormat('dddd') instead. |
|
36 | - * Deprecated since 2.55.0 |
|
37 | - */ |
|
38 | - public $shortLocaleDayOfWeek; |
|
29 | + /** |
|
30 | + * the abbreviated day of week in current locale LC_TIME |
|
31 | + * |
|
32 | + * @var string |
|
33 | + * |
|
34 | + * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
35 | + * Use ->isoFormat('dddd') instead. |
|
36 | + * Deprecated since 2.55.0 |
|
37 | + */ |
|
38 | + public $shortLocaleDayOfWeek; |
|
39 | 39 | |
40 | - /** |
|
41 | - * the month in current locale LC_TIME |
|
42 | - * |
|
43 | - * @var string |
|
44 | - * |
|
45 | - * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
46 | - * Use ->isoFormat('ddd') instead. |
|
47 | - * Deprecated since 2.55.0 |
|
48 | - */ |
|
49 | - public $localeMonth; |
|
40 | + /** |
|
41 | + * the month in current locale LC_TIME |
|
42 | + * |
|
43 | + * @var string |
|
44 | + * |
|
45 | + * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
46 | + * Use ->isoFormat('ddd') instead. |
|
47 | + * Deprecated since 2.55.0 |
|
48 | + */ |
|
49 | + public $localeMonth; |
|
50 | 50 | |
51 | - /** |
|
52 | - * the abbreviated month in current locale LC_TIME |
|
53 | - * |
|
54 | - * @var string |
|
55 | - * |
|
56 | - * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
57 | - * Use ->isoFormat('MMMM') instead. |
|
58 | - * Deprecated since 2.55.0 |
|
59 | - */ |
|
60 | - public $shortLocaleMonth; |
|
51 | + /** |
|
52 | + * the abbreviated month in current locale LC_TIME |
|
53 | + * |
|
54 | + * @var string |
|
55 | + * |
|
56 | + * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
57 | + * Use ->isoFormat('MMMM') instead. |
|
58 | + * Deprecated since 2.55.0 |
|
59 | + */ |
|
60 | + public $shortLocaleMonth; |
|
61 | 61 | } |
@@ -36,184 +36,184 @@ |
||
36 | 36 | */ |
37 | 37 | trait Week |
38 | 38 | { |
39 | - /** |
|
40 | - * Set/get the week number of year using given first day of week and first |
|
41 | - * day of year included in the first week. Or use ISO format if no settings |
|
42 | - * given. |
|
43 | - * |
|
44 | - * @param int|null $year if null, act as a getter, if not null, set the year and return current instance. |
|
45 | - * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday) |
|
46 | - * @param int|null $dayOfYear first day of year included in the week #1 |
|
47 | - * |
|
48 | - * @return int|static |
|
49 | - */ |
|
50 | - public function isoWeekYear($year = null, $dayOfWeek = null, $dayOfYear = null) |
|
51 | - { |
|
52 | - return $this->weekYear( |
|
53 | - $year, |
|
54 | - $dayOfWeek ?? 1, |
|
55 | - $dayOfYear ?? 4 |
|
56 | - ); |
|
57 | - } |
|
58 | - |
|
59 | - /** |
|
60 | - * Set/get the week number of year using given first day of week and first |
|
61 | - * day of year included in the first week. Or use US format if no settings |
|
62 | - * given (Sunday / Jan 6). |
|
63 | - * |
|
64 | - * @param int|null $year if null, act as a getter, if not null, set the year and return current instance. |
|
65 | - * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday) |
|
66 | - * @param int|null $dayOfYear first day of year included in the week #1 |
|
67 | - * |
|
68 | - * @return int|static |
|
69 | - */ |
|
70 | - public function weekYear($year = null, $dayOfWeek = null, $dayOfYear = null) |
|
71 | - { |
|
72 | - $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0; |
|
73 | - $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1; |
|
74 | - |
|
75 | - if ($year !== null) { |
|
76 | - $year = (int) round($year); |
|
77 | - |
|
78 | - if ($this->weekYear(null, $dayOfWeek, $dayOfYear) === $year) { |
|
79 | - return $this->avoidMutation(); |
|
80 | - } |
|
81 | - |
|
82 | - $week = $this->week(null, $dayOfWeek, $dayOfYear); |
|
83 | - $day = $this->dayOfWeek; |
|
84 | - $date = $this->year($year); |
|
85 | - switch ($date->weekYear(null, $dayOfWeek, $dayOfYear) - $year) { |
|
86 | - case 1: |
|
87 | - $date = $date->subWeeks(26); |
|
88 | - |
|
89 | - break; |
|
90 | - case -1: |
|
91 | - $date = $date->addWeeks(26); |
|
92 | - |
|
93 | - break; |
|
94 | - } |
|
95 | - |
|
96 | - $date = $date->addWeeks($week - $date->week(null, $dayOfWeek, $dayOfYear))->startOfWeek($dayOfWeek); |
|
97 | - |
|
98 | - if ($date->dayOfWeek === $day) { |
|
99 | - return $date; |
|
100 | - } |
|
101 | - |
|
102 | - return $date->next($day); |
|
103 | - } |
|
104 | - |
|
105 | - $year = $this->year; |
|
106 | - $day = $this->dayOfYear; |
|
107 | - $date = $this->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
108 | - |
|
109 | - if ($date->year === $year && $day < $date->dayOfYear) { |
|
110 | - return $year - 1; |
|
111 | - } |
|
112 | - |
|
113 | - $date = $this->avoidMutation()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
114 | - |
|
115 | - if ($date->year === $year && $day >= $date->dayOfYear) { |
|
116 | - return $year + 1; |
|
117 | - } |
|
118 | - |
|
119 | - return $year; |
|
120 | - } |
|
121 | - |
|
122 | - /** |
|
123 | - * Get the number of weeks of the current week-year using given first day of week and first |
|
124 | - * day of year included in the first week. Or use ISO format if no settings |
|
125 | - * given. |
|
126 | - * |
|
127 | - * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday) |
|
128 | - * @param int|null $dayOfYear first day of year included in the week #1 |
|
129 | - * |
|
130 | - * @return int |
|
131 | - */ |
|
132 | - public function isoWeeksInYear($dayOfWeek = null, $dayOfYear = null) |
|
133 | - { |
|
134 | - return $this->weeksInYear( |
|
135 | - $dayOfWeek ?? 1, |
|
136 | - $dayOfYear ?? 4 |
|
137 | - ); |
|
138 | - } |
|
139 | - |
|
140 | - /** |
|
141 | - * Get the number of weeks of the current week-year using given first day of week and first |
|
142 | - * day of year included in the first week. Or use US format if no settings |
|
143 | - * given (Sunday / Jan 6). |
|
144 | - * |
|
145 | - * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday) |
|
146 | - * @param int|null $dayOfYear first day of year included in the week #1 |
|
147 | - * |
|
148 | - * @return int |
|
149 | - */ |
|
150 | - public function weeksInYear($dayOfWeek = null, $dayOfYear = null) |
|
151 | - { |
|
152 | - $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0; |
|
153 | - $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1; |
|
154 | - $year = $this->year; |
|
155 | - $start = $this->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
156 | - $startDay = $start->dayOfYear; |
|
157 | - if ($start->year !== $year) { |
|
158 | - $startDay -= $start->daysInYear; |
|
159 | - } |
|
160 | - $end = $this->avoidMutation()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
161 | - $endDay = $end->dayOfYear; |
|
162 | - if ($end->year !== $year) { |
|
163 | - $endDay += $this->daysInYear; |
|
164 | - } |
|
165 | - |
|
166 | - return (int) round(($endDay - $startDay) / 7); |
|
167 | - } |
|
168 | - |
|
169 | - /** |
|
170 | - * Get/set the week number using given first day of week and first |
|
171 | - * day of year included in the first week. Or use US format if no settings |
|
172 | - * given (Sunday / Jan 6). |
|
173 | - * |
|
174 | - * @param int|null $week |
|
175 | - * @param int|null $dayOfWeek |
|
176 | - * @param int|null $dayOfYear |
|
177 | - * |
|
178 | - * @return int|static |
|
179 | - */ |
|
180 | - public function week($week = null, $dayOfWeek = null, $dayOfYear = null) |
|
181 | - { |
|
182 | - $date = $this; |
|
183 | - $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0; |
|
184 | - $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1; |
|
185 | - |
|
186 | - if ($week !== null) { |
|
187 | - return $date->addWeeks(round($week) - $this->week(null, $dayOfWeek, $dayOfYear)); |
|
188 | - } |
|
189 | - |
|
190 | - $start = $date->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
191 | - $end = $date->avoidMutation()->startOfWeek($dayOfWeek); |
|
192 | - if ($start > $end) { |
|
193 | - $start = $start->subWeeks(26)->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
194 | - } |
|
195 | - $week = (int) ($start->diffInDays($end) / 7 + 1); |
|
196 | - |
|
197 | - return $week > $end->weeksInYear($dayOfWeek, $dayOfYear) ? 1 : $week; |
|
198 | - } |
|
199 | - |
|
200 | - /** |
|
201 | - * Get/set the week number using given first day of week and first |
|
202 | - * day of year included in the first week. Or use ISO format if no settings |
|
203 | - * given. |
|
204 | - * |
|
205 | - * @param int|null $week |
|
206 | - * @param int|null $dayOfWeek |
|
207 | - * @param int|null $dayOfYear |
|
208 | - * |
|
209 | - * @return int|static |
|
210 | - */ |
|
211 | - public function isoWeek($week = null, $dayOfWeek = null, $dayOfYear = null) |
|
212 | - { |
|
213 | - return $this->week( |
|
214 | - $week, |
|
215 | - $dayOfWeek ?? 1, |
|
216 | - $dayOfYear ?? 4 |
|
217 | - ); |
|
218 | - } |
|
39 | + /** |
|
40 | + * Set/get the week number of year using given first day of week and first |
|
41 | + * day of year included in the first week. Or use ISO format if no settings |
|
42 | + * given. |
|
43 | + * |
|
44 | + * @param int|null $year if null, act as a getter, if not null, set the year and return current instance. |
|
45 | + * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday) |
|
46 | + * @param int|null $dayOfYear first day of year included in the week #1 |
|
47 | + * |
|
48 | + * @return int|static |
|
49 | + */ |
|
50 | + public function isoWeekYear($year = null, $dayOfWeek = null, $dayOfYear = null) |
|
51 | + { |
|
52 | + return $this->weekYear( |
|
53 | + $year, |
|
54 | + $dayOfWeek ?? 1, |
|
55 | + $dayOfYear ?? 4 |
|
56 | + ); |
|
57 | + } |
|
58 | + |
|
59 | + /** |
|
60 | + * Set/get the week number of year using given first day of week and first |
|
61 | + * day of year included in the first week. Or use US format if no settings |
|
62 | + * given (Sunday / Jan 6). |
|
63 | + * |
|
64 | + * @param int|null $year if null, act as a getter, if not null, set the year and return current instance. |
|
65 | + * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday) |
|
66 | + * @param int|null $dayOfYear first day of year included in the week #1 |
|
67 | + * |
|
68 | + * @return int|static |
|
69 | + */ |
|
70 | + public function weekYear($year = null, $dayOfWeek = null, $dayOfYear = null) |
|
71 | + { |
|
72 | + $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0; |
|
73 | + $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1; |
|
74 | + |
|
75 | + if ($year !== null) { |
|
76 | + $year = (int) round($year); |
|
77 | + |
|
78 | + if ($this->weekYear(null, $dayOfWeek, $dayOfYear) === $year) { |
|
79 | + return $this->avoidMutation(); |
|
80 | + } |
|
81 | + |
|
82 | + $week = $this->week(null, $dayOfWeek, $dayOfYear); |
|
83 | + $day = $this->dayOfWeek; |
|
84 | + $date = $this->year($year); |
|
85 | + switch ($date->weekYear(null, $dayOfWeek, $dayOfYear) - $year) { |
|
86 | + case 1: |
|
87 | + $date = $date->subWeeks(26); |
|
88 | + |
|
89 | + break; |
|
90 | + case -1: |
|
91 | + $date = $date->addWeeks(26); |
|
92 | + |
|
93 | + break; |
|
94 | + } |
|
95 | + |
|
96 | + $date = $date->addWeeks($week - $date->week(null, $dayOfWeek, $dayOfYear))->startOfWeek($dayOfWeek); |
|
97 | + |
|
98 | + if ($date->dayOfWeek === $day) { |
|
99 | + return $date; |
|
100 | + } |
|
101 | + |
|
102 | + return $date->next($day); |
|
103 | + } |
|
104 | + |
|
105 | + $year = $this->year; |
|
106 | + $day = $this->dayOfYear; |
|
107 | + $date = $this->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
108 | + |
|
109 | + if ($date->year === $year && $day < $date->dayOfYear) { |
|
110 | + return $year - 1; |
|
111 | + } |
|
112 | + |
|
113 | + $date = $this->avoidMutation()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
114 | + |
|
115 | + if ($date->year === $year && $day >= $date->dayOfYear) { |
|
116 | + return $year + 1; |
|
117 | + } |
|
118 | + |
|
119 | + return $year; |
|
120 | + } |
|
121 | + |
|
122 | + /** |
|
123 | + * Get the number of weeks of the current week-year using given first day of week and first |
|
124 | + * day of year included in the first week. Or use ISO format if no settings |
|
125 | + * given. |
|
126 | + * |
|
127 | + * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday) |
|
128 | + * @param int|null $dayOfYear first day of year included in the week #1 |
|
129 | + * |
|
130 | + * @return int |
|
131 | + */ |
|
132 | + public function isoWeeksInYear($dayOfWeek = null, $dayOfYear = null) |
|
133 | + { |
|
134 | + return $this->weeksInYear( |
|
135 | + $dayOfWeek ?? 1, |
|
136 | + $dayOfYear ?? 4 |
|
137 | + ); |
|
138 | + } |
|
139 | + |
|
140 | + /** |
|
141 | + * Get the number of weeks of the current week-year using given first day of week and first |
|
142 | + * day of year included in the first week. Or use US format if no settings |
|
143 | + * given (Sunday / Jan 6). |
|
144 | + * |
|
145 | + * @param int|null $dayOfWeek first date of week from 0 (Sunday) to 6 (Saturday) |
|
146 | + * @param int|null $dayOfYear first day of year included in the week #1 |
|
147 | + * |
|
148 | + * @return int |
|
149 | + */ |
|
150 | + public function weeksInYear($dayOfWeek = null, $dayOfYear = null) |
|
151 | + { |
|
152 | + $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0; |
|
153 | + $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1; |
|
154 | + $year = $this->year; |
|
155 | + $start = $this->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
156 | + $startDay = $start->dayOfYear; |
|
157 | + if ($start->year !== $year) { |
|
158 | + $startDay -= $start->daysInYear; |
|
159 | + } |
|
160 | + $end = $this->avoidMutation()->addYear()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
161 | + $endDay = $end->dayOfYear; |
|
162 | + if ($end->year !== $year) { |
|
163 | + $endDay += $this->daysInYear; |
|
164 | + } |
|
165 | + |
|
166 | + return (int) round(($endDay - $startDay) / 7); |
|
167 | + } |
|
168 | + |
|
169 | + /** |
|
170 | + * Get/set the week number using given first day of week and first |
|
171 | + * day of year included in the first week. Or use US format if no settings |
|
172 | + * given (Sunday / Jan 6). |
|
173 | + * |
|
174 | + * @param int|null $week |
|
175 | + * @param int|null $dayOfWeek |
|
176 | + * @param int|null $dayOfYear |
|
177 | + * |
|
178 | + * @return int|static |
|
179 | + */ |
|
180 | + public function week($week = null, $dayOfWeek = null, $dayOfYear = null) |
|
181 | + { |
|
182 | + $date = $this; |
|
183 | + $dayOfWeek = $dayOfWeek ?? $this->getTranslationMessage('first_day_of_week') ?? 0; |
|
184 | + $dayOfYear = $dayOfYear ?? $this->getTranslationMessage('day_of_first_week_of_year') ?? 1; |
|
185 | + |
|
186 | + if ($week !== null) { |
|
187 | + return $date->addWeeks(round($week) - $this->week(null, $dayOfWeek, $dayOfYear)); |
|
188 | + } |
|
189 | + |
|
190 | + $start = $date->avoidMutation()->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
191 | + $end = $date->avoidMutation()->startOfWeek($dayOfWeek); |
|
192 | + if ($start > $end) { |
|
193 | + $start = $start->subWeeks(26)->dayOfYear($dayOfYear)->startOfWeek($dayOfWeek); |
|
194 | + } |
|
195 | + $week = (int) ($start->diffInDays($end) / 7 + 1); |
|
196 | + |
|
197 | + return $week > $end->weeksInYear($dayOfWeek, $dayOfYear) ? 1 : $week; |
|
198 | + } |
|
199 | + |
|
200 | + /** |
|
201 | + * Get/set the week number using given first day of week and first |
|
202 | + * day of year included in the first week. Or use ISO format if no settings |
|
203 | + * given. |
|
204 | + * |
|
205 | + * @param int|null $week |
|
206 | + * @param int|null $dayOfWeek |
|
207 | + * @param int|null $dayOfYear |
|
208 | + * |
|
209 | + * @return int|static |
|
210 | + */ |
|
211 | + public function isoWeek($week = null, $dayOfWeek = null, $dayOfYear = null) |
|
212 | + { |
|
213 | + return $this->week( |
|
214 | + $week, |
|
215 | + $dayOfWeek ?? 1, |
|
216 | + $dayOfYear ?? 4 |
|
217 | + ); |
|
218 | + } |
|
219 | 219 | } |
@@ -21,206 +21,206 @@ |
||
21 | 21 | |
22 | 22 | trait Test |
23 | 23 | { |
24 | - /////////////////////////////////////////////////////////////////// |
|
25 | - ///////////////////////// TESTING AIDS //////////////////////////// |
|
26 | - /////////////////////////////////////////////////////////////////// |
|
27 | - |
|
28 | - /** |
|
29 | - * A test Carbon instance to be returned when now instances are created. |
|
30 | - * |
|
31 | - * @var Closure|static|null |
|
32 | - */ |
|
33 | - protected static $testNow; |
|
34 | - |
|
35 | - /** |
|
36 | - * The timezone to resto to when clearing the time mock. |
|
37 | - * |
|
38 | - * @var string|null |
|
39 | - */ |
|
40 | - protected static $testDefaultTimezone; |
|
41 | - |
|
42 | - /** |
|
43 | - * Set a Carbon instance (real or mock) to be returned when a "now" |
|
44 | - * instance is created. The provided instance will be returned |
|
45 | - * specifically under the following conditions: |
|
46 | - * - A call to the static now() method, ex. Carbon::now() |
|
47 | - * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null) |
|
48 | - * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now') |
|
49 | - * - When a string containing the desired time is passed to Carbon::parse(). |
|
50 | - * |
|
51 | - * Note the timezone parameter was left out of the examples above and |
|
52 | - * has no affect as the mock value will be returned regardless of its value. |
|
53 | - * |
|
54 | - * Only the moment is mocked with setTestNow(), the timezone will still be the one passed |
|
55 | - * as parameter of date_default_timezone_get() as a fallback (see setTestNowAndTimezone()). |
|
56 | - * |
|
57 | - * To clear the test instance call this method using the default |
|
58 | - * parameter of null. |
|
59 | - * |
|
60 | - * /!\ Use this method for unit tests only. |
|
61 | - * |
|
62 | - * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance |
|
63 | - */ |
|
64 | - public static function setTestNow($testNow = null) |
|
65 | - { |
|
66 | - static::$testNow = $testNow instanceof self || $testNow instanceof Closure |
|
67 | - ? $testNow |
|
68 | - : static::make($testNow); |
|
69 | - } |
|
70 | - |
|
71 | - /** |
|
72 | - * Set a Carbon instance (real or mock) to be returned when a "now" |
|
73 | - * instance is created. The provided instance will be returned |
|
74 | - * specifically under the following conditions: |
|
75 | - * - A call to the static now() method, ex. Carbon::now() |
|
76 | - * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null) |
|
77 | - * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now') |
|
78 | - * - When a string containing the desired time is passed to Carbon::parse(). |
|
79 | - * |
|
80 | - * It will also align default timezone (e.g. call date_default_timezone_set()) with |
|
81 | - * the second argument or if null, with the timezone of the given date object. |
|
82 | - * |
|
83 | - * To clear the test instance call this method using the default |
|
84 | - * parameter of null. |
|
85 | - * |
|
86 | - * /!\ Use this method for unit tests only. |
|
87 | - * |
|
88 | - * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance |
|
89 | - */ |
|
90 | - public static function setTestNowAndTimezone($testNow = null, $tz = null) |
|
91 | - { |
|
92 | - if ($testNow) { |
|
93 | - self::$testDefaultTimezone = self::$testDefaultTimezone ?? date_default_timezone_get(); |
|
94 | - } |
|
95 | - |
|
96 | - $useDateInstanceTimezone = $testNow instanceof DateTimeInterface; |
|
97 | - |
|
98 | - if ($useDateInstanceTimezone) { |
|
99 | - self::setDefaultTimezone($testNow->getTimezone()->getName(), $testNow); |
|
100 | - } |
|
101 | - |
|
102 | - static::setTestNow($testNow); |
|
103 | - |
|
104 | - if (!$useDateInstanceTimezone) { |
|
105 | - $now = static::getMockedTestNow(\func_num_args() === 1 ? null : $tz); |
|
106 | - $tzName = $now ? $now->tzName : null; |
|
107 | - self::setDefaultTimezone($tzName ?? self::$testDefaultTimezone ?? 'UTC', $now); |
|
108 | - } |
|
109 | - |
|
110 | - if (!$testNow) { |
|
111 | - self::$testDefaultTimezone = null; |
|
112 | - } |
|
113 | - } |
|
114 | - |
|
115 | - /** |
|
116 | - * Temporarily sets a static date to be used within the callback. |
|
117 | - * Using setTestNow to set the date, executing the callback, then |
|
118 | - * clearing the test instance. |
|
119 | - * |
|
120 | - * /!\ Use this method for unit tests only. |
|
121 | - * |
|
122 | - * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance |
|
123 | - * @param Closure|null $callback |
|
124 | - * |
|
125 | - * @return mixed |
|
126 | - */ |
|
127 | - public static function withTestNow($testNow = null, $callback = null) |
|
128 | - { |
|
129 | - static::setTestNow($testNow); |
|
130 | - |
|
131 | - try { |
|
132 | - $result = $callback(); |
|
133 | - } finally { |
|
134 | - static::setTestNow(); |
|
135 | - } |
|
136 | - |
|
137 | - return $result; |
|
138 | - } |
|
139 | - |
|
140 | - /** |
|
141 | - * Get the Carbon instance (real or mock) to be returned when a "now" |
|
142 | - * instance is created. |
|
143 | - * |
|
144 | - * @return Closure|static the current instance used for testing |
|
145 | - */ |
|
146 | - public static function getTestNow() |
|
147 | - { |
|
148 | - return static::$testNow; |
|
149 | - } |
|
150 | - |
|
151 | - /** |
|
152 | - * Determine if there is a valid test instance set. A valid test instance |
|
153 | - * is anything that is not null. |
|
154 | - * |
|
155 | - * @return bool true if there is a test instance, otherwise false |
|
156 | - */ |
|
157 | - public static function hasTestNow() |
|
158 | - { |
|
159 | - return static::getTestNow() !== null; |
|
160 | - } |
|
161 | - |
|
162 | - /** |
|
163 | - * Get the mocked date passed in setTestNow() and if it's a Closure, execute it. |
|
164 | - * |
|
165 | - * @param string|\DateTimeZone $tz |
|
166 | - * |
|
167 | - * @return \Carbon\CarbonImmutable|\Carbon\Carbon|null |
|
168 | - */ |
|
169 | - protected static function getMockedTestNow($tz) |
|
170 | - { |
|
171 | - $testNow = static::getTestNow(); |
|
172 | - |
|
173 | - if ($testNow instanceof Closure) { |
|
174 | - $realNow = new DateTimeImmutable('now'); |
|
175 | - $testNow = $testNow(static::parse( |
|
176 | - $realNow->format('Y-m-d H:i:s.u'), |
|
177 | - $tz ?: $realNow->getTimezone() |
|
178 | - )); |
|
179 | - } |
|
180 | - /* @var \Carbon\CarbonImmutable|\Carbon\Carbon|null $testNow */ |
|
181 | - |
|
182 | - return $testNow instanceof CarbonInterface |
|
183 | - ? $testNow->avoidMutation()->tz($tz) |
|
184 | - : $testNow; |
|
185 | - } |
|
186 | - |
|
187 | - protected static function mockConstructorParameters(&$time, $tz) |
|
188 | - { |
|
189 | - /** @var \Carbon\CarbonImmutable|\Carbon\Carbon $testInstance */ |
|
190 | - $testInstance = clone static::getMockedTestNow($tz); |
|
191 | - |
|
192 | - if (static::hasRelativeKeywords($time)) { |
|
193 | - $testInstance = $testInstance->modify($time); |
|
194 | - } |
|
195 | - |
|
196 | - $time = $testInstance instanceof self |
|
197 | - ? $testInstance->rawFormat(static::MOCK_DATETIME_FORMAT) |
|
198 | - : $testInstance->format(static::MOCK_DATETIME_FORMAT); |
|
199 | - } |
|
200 | - |
|
201 | - private static function setDefaultTimezone($timezone, DateTimeInterface $date = null) |
|
202 | - { |
|
203 | - $previous = null; |
|
204 | - $success = false; |
|
205 | - |
|
206 | - try { |
|
207 | - $success = date_default_timezone_set($timezone); |
|
208 | - } catch (Throwable $exception) { |
|
209 | - $previous = $exception; |
|
210 | - } |
|
211 | - |
|
212 | - if (!$success) { |
|
213 | - $suggestion = @CarbonTimeZone::create($timezone)->toRegionName($date); |
|
214 | - |
|
215 | - throw new InvalidArgumentException( |
|
216 | - "Timezone ID '$timezone' is invalid". |
|
217 | - ($suggestion && $suggestion !== $timezone ? ", did you mean '$suggestion'?" : '.')."\n". |
|
218 | - "It must be one of the IDs from DateTimeZone::listIdentifiers(),\n". |
|
219 | - 'For the record, hours/minutes offset are relevant only for a particular moment, '. |
|
220 | - 'but not as a default timezone.', |
|
221 | - 0, |
|
222 | - $previous |
|
223 | - ); |
|
224 | - } |
|
225 | - } |
|
24 | + /////////////////////////////////////////////////////////////////// |
|
25 | + ///////////////////////// TESTING AIDS //////////////////////////// |
|
26 | + /////////////////////////////////////////////////////////////////// |
|
27 | + |
|
28 | + /** |
|
29 | + * A test Carbon instance to be returned when now instances are created. |
|
30 | + * |
|
31 | + * @var Closure|static|null |
|
32 | + */ |
|
33 | + protected static $testNow; |
|
34 | + |
|
35 | + /** |
|
36 | + * The timezone to resto to when clearing the time mock. |
|
37 | + * |
|
38 | + * @var string|null |
|
39 | + */ |
|
40 | + protected static $testDefaultTimezone; |
|
41 | + |
|
42 | + /** |
|
43 | + * Set a Carbon instance (real or mock) to be returned when a "now" |
|
44 | + * instance is created. The provided instance will be returned |
|
45 | + * specifically under the following conditions: |
|
46 | + * - A call to the static now() method, ex. Carbon::now() |
|
47 | + * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null) |
|
48 | + * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now') |
|
49 | + * - When a string containing the desired time is passed to Carbon::parse(). |
|
50 | + * |
|
51 | + * Note the timezone parameter was left out of the examples above and |
|
52 | + * has no affect as the mock value will be returned regardless of its value. |
|
53 | + * |
|
54 | + * Only the moment is mocked with setTestNow(), the timezone will still be the one passed |
|
55 | + * as parameter of date_default_timezone_get() as a fallback (see setTestNowAndTimezone()). |
|
56 | + * |
|
57 | + * To clear the test instance call this method using the default |
|
58 | + * parameter of null. |
|
59 | + * |
|
60 | + * /!\ Use this method for unit tests only. |
|
61 | + * |
|
62 | + * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance |
|
63 | + */ |
|
64 | + public static function setTestNow($testNow = null) |
|
65 | + { |
|
66 | + static::$testNow = $testNow instanceof self || $testNow instanceof Closure |
|
67 | + ? $testNow |
|
68 | + : static::make($testNow); |
|
69 | + } |
|
70 | + |
|
71 | + /** |
|
72 | + * Set a Carbon instance (real or mock) to be returned when a "now" |
|
73 | + * instance is created. The provided instance will be returned |
|
74 | + * specifically under the following conditions: |
|
75 | + * - A call to the static now() method, ex. Carbon::now() |
|
76 | + * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null) |
|
77 | + * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now') |
|
78 | + * - When a string containing the desired time is passed to Carbon::parse(). |
|
79 | + * |
|
80 | + * It will also align default timezone (e.g. call date_default_timezone_set()) with |
|
81 | + * the second argument or if null, with the timezone of the given date object. |
|
82 | + * |
|
83 | + * To clear the test instance call this method using the default |
|
84 | + * parameter of null. |
|
85 | + * |
|
86 | + * /!\ Use this method for unit tests only. |
|
87 | + * |
|
88 | + * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance |
|
89 | + */ |
|
90 | + public static function setTestNowAndTimezone($testNow = null, $tz = null) |
|
91 | + { |
|
92 | + if ($testNow) { |
|
93 | + self::$testDefaultTimezone = self::$testDefaultTimezone ?? date_default_timezone_get(); |
|
94 | + } |
|
95 | + |
|
96 | + $useDateInstanceTimezone = $testNow instanceof DateTimeInterface; |
|
97 | + |
|
98 | + if ($useDateInstanceTimezone) { |
|
99 | + self::setDefaultTimezone($testNow->getTimezone()->getName(), $testNow); |
|
100 | + } |
|
101 | + |
|
102 | + static::setTestNow($testNow); |
|
103 | + |
|
104 | + if (!$useDateInstanceTimezone) { |
|
105 | + $now = static::getMockedTestNow(\func_num_args() === 1 ? null : $tz); |
|
106 | + $tzName = $now ? $now->tzName : null; |
|
107 | + self::setDefaultTimezone($tzName ?? self::$testDefaultTimezone ?? 'UTC', $now); |
|
108 | + } |
|
109 | + |
|
110 | + if (!$testNow) { |
|
111 | + self::$testDefaultTimezone = null; |
|
112 | + } |
|
113 | + } |
|
114 | + |
|
115 | + /** |
|
116 | + * Temporarily sets a static date to be used within the callback. |
|
117 | + * Using setTestNow to set the date, executing the callback, then |
|
118 | + * clearing the test instance. |
|
119 | + * |
|
120 | + * /!\ Use this method for unit tests only. |
|
121 | + * |
|
122 | + * @param DateTimeInterface|Closure|static|string|false|null $testNow real or mock Carbon instance |
|
123 | + * @param Closure|null $callback |
|
124 | + * |
|
125 | + * @return mixed |
|
126 | + */ |
|
127 | + public static function withTestNow($testNow = null, $callback = null) |
|
128 | + { |
|
129 | + static::setTestNow($testNow); |
|
130 | + |
|
131 | + try { |
|
132 | + $result = $callback(); |
|
133 | + } finally { |
|
134 | + static::setTestNow(); |
|
135 | + } |
|
136 | + |
|
137 | + return $result; |
|
138 | + } |
|
139 | + |
|
140 | + /** |
|
141 | + * Get the Carbon instance (real or mock) to be returned when a "now" |
|
142 | + * instance is created. |
|
143 | + * |
|
144 | + * @return Closure|static the current instance used for testing |
|
145 | + */ |
|
146 | + public static function getTestNow() |
|
147 | + { |
|
148 | + return static::$testNow; |
|
149 | + } |
|
150 | + |
|
151 | + /** |
|
152 | + * Determine if there is a valid test instance set. A valid test instance |
|
153 | + * is anything that is not null. |
|
154 | + * |
|
155 | + * @return bool true if there is a test instance, otherwise false |
|
156 | + */ |
|
157 | + public static function hasTestNow() |
|
158 | + { |
|
159 | + return static::getTestNow() !== null; |
|
160 | + } |
|
161 | + |
|
162 | + /** |
|
163 | + * Get the mocked date passed in setTestNow() and if it's a Closure, execute it. |
|
164 | + * |
|
165 | + * @param string|\DateTimeZone $tz |
|
166 | + * |
|
167 | + * @return \Carbon\CarbonImmutable|\Carbon\Carbon|null |
|
168 | + */ |
|
169 | + protected static function getMockedTestNow($tz) |
|
170 | + { |
|
171 | + $testNow = static::getTestNow(); |
|
172 | + |
|
173 | + if ($testNow instanceof Closure) { |
|
174 | + $realNow = new DateTimeImmutable('now'); |
|
175 | + $testNow = $testNow(static::parse( |
|
176 | + $realNow->format('Y-m-d H:i:s.u'), |
|
177 | + $tz ?: $realNow->getTimezone() |
|
178 | + )); |
|
179 | + } |
|
180 | + /* @var \Carbon\CarbonImmutable|\Carbon\Carbon|null $testNow */ |
|
181 | + |
|
182 | + return $testNow instanceof CarbonInterface |
|
183 | + ? $testNow->avoidMutation()->tz($tz) |
|
184 | + : $testNow; |
|
185 | + } |
|
186 | + |
|
187 | + protected static function mockConstructorParameters(&$time, $tz) |
|
188 | + { |
|
189 | + /** @var \Carbon\CarbonImmutable|\Carbon\Carbon $testInstance */ |
|
190 | + $testInstance = clone static::getMockedTestNow($tz); |
|
191 | + |
|
192 | + if (static::hasRelativeKeywords($time)) { |
|
193 | + $testInstance = $testInstance->modify($time); |
|
194 | + } |
|
195 | + |
|
196 | + $time = $testInstance instanceof self |
|
197 | + ? $testInstance->rawFormat(static::MOCK_DATETIME_FORMAT) |
|
198 | + : $testInstance->format(static::MOCK_DATETIME_FORMAT); |
|
199 | + } |
|
200 | + |
|
201 | + private static function setDefaultTimezone($timezone, DateTimeInterface $date = null) |
|
202 | + { |
|
203 | + $previous = null; |
|
204 | + $success = false; |
|
205 | + |
|
206 | + try { |
|
207 | + $success = date_default_timezone_set($timezone); |
|
208 | + } catch (Throwable $exception) { |
|
209 | + $previous = $exception; |
|
210 | + } |
|
211 | + |
|
212 | + if (!$success) { |
|
213 | + $suggestion = @CarbonTimeZone::create($timezone)->toRegionName($date); |
|
214 | + |
|
215 | + throw new InvalidArgumentException( |
|
216 | + "Timezone ID '$timezone' is invalid". |
|
217 | + ($suggestion && $suggestion !== $timezone ? ", did you mean '$suggestion'?" : '.')."\n". |
|
218 | + "It must be one of the IDs from DateTimeZone::listIdentifiers(),\n". |
|
219 | + 'For the record, hours/minutes offset are relevant only for a particular moment, '. |
|
220 | + 'but not as a default timezone.', |
|
221 | + 0, |
|
222 | + $previous |
|
223 | + ); |
|
224 | + } |
|
225 | + } |
|
226 | 226 | } |
@@ -20,38 +20,38 @@ |
||
20 | 20 | */ |
21 | 21 | trait IntervalRounding |
22 | 22 | { |
23 | - protected function callRoundMethod(string $method, array $parameters) |
|
24 | - { |
|
25 | - $action = substr($method, 0, 4); |
|
23 | + protected function callRoundMethod(string $method, array $parameters) |
|
24 | + { |
|
25 | + $action = substr($method, 0, 4); |
|
26 | 26 | |
27 | - if ($action !== 'ceil') { |
|
28 | - $action = substr($method, 0, 5); |
|
29 | - } |
|
27 | + if ($action !== 'ceil') { |
|
28 | + $action = substr($method, 0, 5); |
|
29 | + } |
|
30 | 30 | |
31 | - if (\in_array($action, ['round', 'floor', 'ceil'])) { |
|
32 | - return $this->{$action.'Unit'}(substr($method, \strlen($action)), ...$parameters); |
|
33 | - } |
|
31 | + if (\in_array($action, ['round', 'floor', 'ceil'])) { |
|
32 | + return $this->{$action.'Unit'}(substr($method, \strlen($action)), ...$parameters); |
|
33 | + } |
|
34 | 34 | |
35 | - return null; |
|
36 | - } |
|
35 | + return null; |
|
36 | + } |
|
37 | 37 | |
38 | - protected function roundWith($precision, $function) |
|
39 | - { |
|
40 | - $unit = 'second'; |
|
38 | + protected function roundWith($precision, $function) |
|
39 | + { |
|
40 | + $unit = 'second'; |
|
41 | 41 | |
42 | - if ($precision instanceof DateInterval) { |
|
43 | - $precision = (string) CarbonInterval::instance($precision); |
|
44 | - } |
|
42 | + if ($precision instanceof DateInterval) { |
|
43 | + $precision = (string) CarbonInterval::instance($precision); |
|
44 | + } |
|
45 | 45 | |
46 | - if (\is_string($precision) && preg_match('/^\s*(?<precision>\d+)?\s*(?<unit>\w+)(?<other>\W.*)?$/', $precision, $match)) { |
|
47 | - if (trim($match['other'] ?? '') !== '') { |
|
48 | - throw new InvalidIntervalException('Rounding is only possible with single unit intervals.'); |
|
49 | - } |
|
46 | + if (\is_string($precision) && preg_match('/^\s*(?<precision>\d+)?\s*(?<unit>\w+)(?<other>\W.*)?$/', $precision, $match)) { |
|
47 | + if (trim($match['other'] ?? '') !== '') { |
|
48 | + throw new InvalidIntervalException('Rounding is only possible with single unit intervals.'); |
|
49 | + } |
|
50 | 50 | |
51 | - $precision = (int) ($match['precision'] ?: 1); |
|
52 | - $unit = $match['unit']; |
|
53 | - } |
|
51 | + $precision = (int) ($match['precision'] ?: 1); |
|
52 | + $unit = $match['unit']; |
|
53 | + } |
|
54 | 54 | |
55 | - return $this->roundUnit($unit, $precision, $function); |
|
56 | - } |
|
55 | + return $this->roundUnit($unit, $precision, $function); |
|
56 | + } |
|
57 | 57 | } |
@@ -1922,13 +1922,13 @@ discard block |
||
1922 | 1922 | 'DD' => ['rawFormat', ['d']], |
1923 | 1923 | 'Do' => ['ordinal', ['day', 'D']], |
1924 | 1924 | 'd' => 'dayOfWeek', |
1925 | - 'dd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1925 | + 'dd' => function(CarbonInterface $date, $originalFormat = null) { |
|
1926 | 1926 | return $date->getTranslatedMinDayName($originalFormat); |
1927 | 1927 | }, |
1928 | - 'ddd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1928 | + 'ddd' => function(CarbonInterface $date, $originalFormat = null) { |
|
1929 | 1929 | return $date->getTranslatedShortDayName($originalFormat); |
1930 | 1930 | }, |
1931 | - 'dddd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1931 | + 'dddd' => function(CarbonInterface $date, $originalFormat = null) { |
|
1932 | 1932 | return $date->getTranslatedDayName($originalFormat); |
1933 | 1933 | }, |
1934 | 1934 | 'DDD' => 'dayOfYear', |
@@ -1952,34 +1952,34 @@ discard block |
||
1952 | 1952 | 'A' => 'upperMeridiem', |
1953 | 1953 | 's' => 'second', |
1954 | 1954 | 'ss' => ['getPaddedUnit', ['second']], |
1955 | - 'S' => function (CarbonInterface $date) { |
|
1955 | + 'S' => function(CarbonInterface $date) { |
|
1956 | 1956 | return (string) floor($date->micro / 100000); |
1957 | 1957 | }, |
1958 | - 'SS' => function (CarbonInterface $date) { |
|
1958 | + 'SS' => function(CarbonInterface $date) { |
|
1959 | 1959 | return str_pad((string) floor($date->micro / 10000), 2, '0', STR_PAD_LEFT); |
1960 | 1960 | }, |
1961 | - 'SSS' => function (CarbonInterface $date) { |
|
1961 | + 'SSS' => function(CarbonInterface $date) { |
|
1962 | 1962 | return str_pad((string) floor($date->micro / 1000), 3, '0', STR_PAD_LEFT); |
1963 | 1963 | }, |
1964 | - 'SSSS' => function (CarbonInterface $date) { |
|
1964 | + 'SSSS' => function(CarbonInterface $date) { |
|
1965 | 1965 | return str_pad((string) floor($date->micro / 100), 4, '0', STR_PAD_LEFT); |
1966 | 1966 | }, |
1967 | - 'SSSSS' => function (CarbonInterface $date) { |
|
1967 | + 'SSSSS' => function(CarbonInterface $date) { |
|
1968 | 1968 | return str_pad((string) floor($date->micro / 10), 5, '0', STR_PAD_LEFT); |
1969 | 1969 | }, |
1970 | 1970 | 'SSSSSS' => ['getPaddedUnit', ['micro', 6]], |
1971 | - 'SSSSSSS' => function (CarbonInterface $date) { |
|
1971 | + 'SSSSSSS' => function(CarbonInterface $date) { |
|
1972 | 1972 | return str_pad((string) floor($date->micro * 10), 7, '0', STR_PAD_LEFT); |
1973 | 1973 | }, |
1974 | - 'SSSSSSSS' => function (CarbonInterface $date) { |
|
1974 | + 'SSSSSSSS' => function(CarbonInterface $date) { |
|
1975 | 1975 | return str_pad((string) floor($date->micro * 100), 8, '0', STR_PAD_LEFT); |
1976 | 1976 | }, |
1977 | - 'SSSSSSSSS' => function (CarbonInterface $date) { |
|
1977 | + 'SSSSSSSSS' => function(CarbonInterface $date) { |
|
1978 | 1978 | return str_pad((string) floor($date->micro * 1000), 9, '0', STR_PAD_LEFT); |
1979 | 1979 | }, |
1980 | 1980 | 'M' => 'month', |
1981 | 1981 | 'MM' => ['rawFormat', ['m']], |
1982 | - 'MMM' => function (CarbonInterface $date, $originalFormat = null) { |
|
1982 | + 'MMM' => function(CarbonInterface $date, $originalFormat = null) { |
|
1983 | 1983 | $month = $date->getTranslatedShortMonthName($originalFormat); |
1984 | 1984 | $suffix = $date->getTranslationMessage('mmm_suffix'); |
1985 | 1985 | if ($suffix && $month !== $date->monthName) { |
@@ -1988,7 +1988,7 @@ discard block |
||
1988 | 1988 | |
1989 | 1989 | return $month; |
1990 | 1990 | }, |
1991 | - 'MMMM' => function (CarbonInterface $date, $originalFormat = null) { |
|
1991 | + 'MMMM' => function(CarbonInterface $date, $originalFormat = null) { |
|
1992 | 1992 | return $date->getTranslatedMonthName($originalFormat); |
1993 | 1993 | }, |
1994 | 1994 | 'Mo' => ['ordinal', ['month', 'M']], |
@@ -2016,7 +2016,7 @@ discard block |
||
2016 | 2016 | 'YY' => ['rawFormat', ['y']], |
2017 | 2017 | 'YYYY' => ['getPaddedUnit', ['year', 4]], |
2018 | 2018 | 'YYYYY' => ['getPaddedUnit', ['year', 5]], |
2019 | - 'YYYYYY' => function (CarbonInterface $date) { |
|
2019 | + 'YYYYYY' => function(CarbonInterface $date) { |
|
2020 | 2020 | return ($date->year < 0 ? '' : '+').$date->getPaddedUnit('year', 6); |
2021 | 2021 | }, |
2022 | 2022 | 'z' => ['rawFormat', ['T']], |
@@ -2169,7 +2169,7 @@ discard block |
||
2169 | 2169 | $code = $match[0]; |
2170 | 2170 | $sequence = $formats[$code] ?? preg_replace_callback( |
2171 | 2171 | '/MMMM|MM|DD|dddd/', |
2172 | - function ($code) { |
|
2172 | + function($code) { |
|
2173 | 2173 | return mb_substr($code[0], 1); |
2174 | 2174 | }, |
2175 | 2175 | $formats[strtoupper($code)] ?? '' |
@@ -2229,7 +2229,7 @@ discard block |
||
2229 | 2229 | 'j' => true, |
2230 | 2230 | 'l' => 'dddd', |
2231 | 2231 | 'N' => true, |
2232 | - 'S' => function ($date) { |
|
2232 | + 'S' => function($date) { |
|
2233 | 2233 | $day = $date->rawFormat('j'); |
2234 | 2234 | |
2235 | 2235 | return str_replace((string) $day, '', $date->isoFormat('Do')); |
@@ -2375,7 +2375,7 @@ discard block |
||
2375 | 2375 | |
2376 | 2376 | protected static function executeStaticCallable($macro, ...$parameters) |
2377 | 2377 | { |
2378 | - return static::bindMacroContext(null, function () use (&$macro, &$parameters) { |
|
2378 | + return static::bindMacroContext(null, function() use (&$macro, &$parameters) { |
|
2379 | 2379 | if ($macro instanceof Closure) { |
2380 | 2380 | $boundMacro = @Closure::bind($macro, null, static::class); |
2381 | 2381 | |
@@ -2429,7 +2429,7 @@ discard block |
||
2429 | 2429 | $unit = static::singularUnit($unit); |
2430 | 2430 | $dateUnits = ['year', 'month', 'day']; |
2431 | 2431 | if (\in_array($unit, $dateUnits)) { |
2432 | - return $this->setDate(...array_map(function ($name) use ($unit, $value) { |
|
2432 | + return $this->setDate(...array_map(function($name) use ($unit, $value) { |
|
2433 | 2433 | return (int) ($name === $unit ? $value : $this->$name); |
2434 | 2434 | }, $dateUnits)); |
2435 | 2435 | } |
@@ -2442,7 +2442,7 @@ discard block |
||
2442 | 2442 | $unit = 'micro'; |
2443 | 2443 | } |
2444 | 2444 | |
2445 | - return $this->setTime(...array_map(function ($name) use ($unit, $value) { |
|
2445 | + return $this->setTime(...array_map(function($name) use ($unit, $value) { |
|
2446 | 2446 | return (int) ($name === $unit ? $value : $this->$name); |
2447 | 2447 | }, $units)); |
2448 | 2448 | } |
@@ -2504,7 +2504,7 @@ discard block |
||
2504 | 2504 | |
2505 | 2505 | protected function executeCallableWithContext($macro, ...$parameters) |
2506 | 2506 | { |
2507 | - return static::bindMacroContext($this, function () use (&$macro, &$parameters) { |
|
2507 | + return static::bindMacroContext($this, function() use (&$macro, &$parameters) { |
|
2508 | 2508 | return $this->executeCallable($macro, ...$parameters); |
2509 | 2509 | }); |
2510 | 2510 | } |
@@ -2550,7 +2550,7 @@ discard block |
||
2550 | 2550 | $syntaxPattern = implode('|', array_keys($diffSyntaxModes)); |
2551 | 2551 | |
2552 | 2552 | if (preg_match("/^(?<size>$sizePattern)(?<syntax>$syntaxPattern)DiffForHumans$/", $method, $match)) { |
2553 | - $dates = array_filter($parameters, function ($parameter) { |
|
2553 | + $dates = array_filter($parameters, function($parameter) { |
|
2554 | 2554 | return $parameter instanceof DateTimeInterface; |
2555 | 2555 | }); |
2556 | 2556 | $other = null; |
@@ -2670,7 +2670,7 @@ discard block |
||
2670 | 2670 | } |
2671 | 2671 | } |
2672 | 2672 | |
2673 | - return static::bindMacroContext($this, function () use (&$method, &$parameters) { |
|
2673 | + return static::bindMacroContext($this, function() use (&$method, &$parameters) { |
|
2674 | 2674 | $macro = $this->getLocalMacro($method); |
2675 | 2675 | |
2676 | 2676 | if (!$macro) { |
@@ -2613,7 +2613,7 @@ discard block |
||
2613 | 2613 | if (str_starts_with($unit, 'Real')) { |
2614 | 2614 | $unit = static::singularUnit(substr($unit, 4)); |
2615 | 2615 | |
2616 | - return $this->{"{$action}RealUnit"}($unit, ...$parameters); |
|
2616 | + return $this->{"{$action}realunit"}($unit, ...$parameters); |
|
2617 | 2617 | } |
2618 | 2618 | |
2619 | 2619 | if (preg_match('/^(Month|Quarter|Year|Decade|Century|Centurie|Millennium|Millennia)s?(No|With|Without|WithNo)Overflow$/', $unit, $match)) { |
@@ -2625,7 +2625,7 @@ discard block |
||
2625 | 2625 | } |
2626 | 2626 | |
2627 | 2627 | if (static::isModifiableUnit($unit)) { |
2628 | - return $this->{"{$action}Unit"}($unit, $parameters[0] ?? 1, $overflow); |
|
2628 | + return $this->{"{$action}unit"}($unit, $parameters[0] ?? 1, $overflow); |
|
2629 | 2629 | } |
2630 | 2630 | |
2631 | 2631 | $sixFirstLetters = substr($unit, 0, 6); |
@@ -526,2172 +526,2172 @@ |
||
526 | 526 | */ |
527 | 527 | trait Date |
528 | 528 | { |
529 | - use Boundaries; |
|
530 | - use Comparison; |
|
531 | - use Converter; |
|
532 | - use Creator; |
|
533 | - use Difference; |
|
534 | - use Macro; |
|
535 | - use Modifiers; |
|
536 | - use Mutability; |
|
537 | - use ObjectInitialisation; |
|
538 | - use Options; |
|
539 | - use Rounding; |
|
540 | - use Serialization; |
|
541 | - use Test; |
|
542 | - use Timestamp; |
|
543 | - use Units; |
|
544 | - use Week; |
|
545 | - |
|
546 | - /** |
|
547 | - * Names of days of the week. |
|
548 | - * |
|
549 | - * @var array |
|
550 | - */ |
|
551 | - protected static $days = [ |
|
552 | - // @call isDayOfWeek |
|
553 | - CarbonInterface::SUNDAY => 'Sunday', |
|
554 | - // @call isDayOfWeek |
|
555 | - CarbonInterface::MONDAY => 'Monday', |
|
556 | - // @call isDayOfWeek |
|
557 | - CarbonInterface::TUESDAY => 'Tuesday', |
|
558 | - // @call isDayOfWeek |
|
559 | - CarbonInterface::WEDNESDAY => 'Wednesday', |
|
560 | - // @call isDayOfWeek |
|
561 | - CarbonInterface::THURSDAY => 'Thursday', |
|
562 | - // @call isDayOfWeek |
|
563 | - CarbonInterface::FRIDAY => 'Friday', |
|
564 | - // @call isDayOfWeek |
|
565 | - CarbonInterface::SATURDAY => 'Saturday', |
|
566 | - ]; |
|
567 | - |
|
568 | - /** |
|
569 | - * Will UTF8 encoding be used to print localized date/time ? |
|
570 | - * |
|
571 | - * @var bool |
|
572 | - */ |
|
573 | - protected static $utf8 = false; |
|
574 | - |
|
575 | - /** |
|
576 | - * List of unit and magic methods associated as doc-comments. |
|
577 | - * |
|
578 | - * @var array |
|
579 | - */ |
|
580 | - protected static $units = [ |
|
581 | - // @call setUnit |
|
582 | - // @call addUnit |
|
583 | - 'year', |
|
584 | - // @call setUnit |
|
585 | - // @call addUnit |
|
586 | - 'month', |
|
587 | - // @call setUnit |
|
588 | - // @call addUnit |
|
589 | - 'day', |
|
590 | - // @call setUnit |
|
591 | - // @call addUnit |
|
592 | - 'hour', |
|
593 | - // @call setUnit |
|
594 | - // @call addUnit |
|
595 | - 'minute', |
|
596 | - // @call setUnit |
|
597 | - // @call addUnit |
|
598 | - 'second', |
|
599 | - // @call setUnit |
|
600 | - // @call addUnit |
|
601 | - 'milli', |
|
602 | - // @call setUnit |
|
603 | - // @call addUnit |
|
604 | - 'millisecond', |
|
605 | - // @call setUnit |
|
606 | - // @call addUnit |
|
607 | - 'micro', |
|
608 | - // @call setUnit |
|
609 | - // @call addUnit |
|
610 | - 'microsecond', |
|
611 | - ]; |
|
612 | - |
|
613 | - /** |
|
614 | - * Creates a DateTimeZone from a string, DateTimeZone or integer offset. |
|
615 | - * |
|
616 | - * @param DateTimeZone|string|int|null $object original value to get CarbonTimeZone from it. |
|
617 | - * @param DateTimeZone|string|int|null $objectDump dump of the object for error messages. |
|
618 | - * |
|
619 | - * @throws InvalidTimeZoneException |
|
620 | - * |
|
621 | - * @return CarbonTimeZone|false |
|
622 | - */ |
|
623 | - protected static function safeCreateDateTimeZone($object, $objectDump = null) |
|
624 | - { |
|
625 | - return CarbonTimeZone::instance($object, $objectDump); |
|
626 | - } |
|
627 | - |
|
628 | - /** |
|
629 | - * Get the TimeZone associated with the Carbon instance (as CarbonTimeZone). |
|
630 | - * |
|
631 | - * @return CarbonTimeZone |
|
632 | - * |
|
633 | - * @link https://php.net/manual/en/datetime.gettimezone.php |
|
634 | - */ |
|
635 | - #[ReturnTypeWillChange] |
|
636 | - public function getTimezone() |
|
637 | - { |
|
638 | - return CarbonTimeZone::instance(parent::getTimezone()); |
|
639 | - } |
|
640 | - |
|
641 | - /** |
|
642 | - * List of minimum and maximums for each unit. |
|
643 | - * |
|
644 | - * @return array |
|
645 | - */ |
|
646 | - protected static function getRangesByUnit(int $daysInMonth = 31): array |
|
647 | - { |
|
648 | - return [ |
|
649 | - // @call roundUnit |
|
650 | - 'year' => [1, 9999], |
|
651 | - // @call roundUnit |
|
652 | - 'month' => [1, static::MONTHS_PER_YEAR], |
|
653 | - // @call roundUnit |
|
654 | - 'day' => [1, $daysInMonth], |
|
655 | - // @call roundUnit |
|
656 | - 'hour' => [0, static::HOURS_PER_DAY - 1], |
|
657 | - // @call roundUnit |
|
658 | - 'minute' => [0, static::MINUTES_PER_HOUR - 1], |
|
659 | - // @call roundUnit |
|
660 | - 'second' => [0, static::SECONDS_PER_MINUTE - 1], |
|
661 | - ]; |
|
662 | - } |
|
663 | - |
|
664 | - /** |
|
665 | - * Get a copy of the instance. |
|
666 | - * |
|
667 | - * @return static |
|
668 | - */ |
|
669 | - public function copy() |
|
670 | - { |
|
671 | - return clone $this; |
|
672 | - } |
|
673 | - |
|
674 | - /** |
|
675 | - * @alias copy |
|
676 | - * |
|
677 | - * Get a copy of the instance. |
|
678 | - * |
|
679 | - * @return static |
|
680 | - */ |
|
681 | - public function clone() |
|
682 | - { |
|
683 | - return clone $this; |
|
684 | - } |
|
685 | - |
|
686 | - /** |
|
687 | - * Clone the current instance if it's mutable. |
|
688 | - * |
|
689 | - * This method is convenient to ensure you don't mutate the initial object |
|
690 | - * but avoid to make a useless copy of it if it's already immutable. |
|
691 | - * |
|
692 | - * @return static |
|
693 | - */ |
|
694 | - public function avoidMutation(): self |
|
695 | - { |
|
696 | - if ($this instanceof DateTimeImmutable) { |
|
697 | - return $this; |
|
698 | - } |
|
699 | - |
|
700 | - return clone $this; |
|
701 | - } |
|
702 | - |
|
703 | - /** |
|
704 | - * Returns a present instance in the same timezone. |
|
705 | - * |
|
706 | - * @return static |
|
707 | - */ |
|
708 | - public function nowWithSameTz() |
|
709 | - { |
|
710 | - return static::now($this->getTimezone()); |
|
711 | - } |
|
712 | - |
|
713 | - /** |
|
714 | - * Throws an exception if the given object is not a DateTime and does not implement DateTimeInterface. |
|
715 | - * |
|
716 | - * @param mixed $date |
|
717 | - * @param string|array $other |
|
718 | - * |
|
719 | - * @throws InvalidTypeException |
|
720 | - */ |
|
721 | - protected static function expectDateTime($date, $other = []) |
|
722 | - { |
|
723 | - $message = 'Expected '; |
|
724 | - foreach ((array) $other as $expect) { |
|
725 | - $message .= "$expect, "; |
|
726 | - } |
|
727 | - |
|
728 | - if (!$date instanceof DateTime && !$date instanceof DateTimeInterface) { |
|
729 | - throw new InvalidTypeException( |
|
730 | - $message.'DateTime or DateTimeInterface, '. |
|
731 | - (\is_object($date) ? \get_class($date) : \gettype($date)).' given' |
|
732 | - ); |
|
733 | - } |
|
734 | - } |
|
735 | - |
|
736 | - /** |
|
737 | - * Return the Carbon instance passed through, a now instance in the same timezone |
|
738 | - * if null given or parse the input if string given. |
|
739 | - * |
|
740 | - * @param Carbon|DateTimeInterface|string|null $date |
|
741 | - * |
|
742 | - * @return static |
|
743 | - */ |
|
744 | - protected function resolveCarbon($date = null) |
|
745 | - { |
|
746 | - if (!$date) { |
|
747 | - return $this->nowWithSameTz(); |
|
748 | - } |
|
749 | - |
|
750 | - if (\is_string($date)) { |
|
751 | - return static::parse($date, $this->getTimezone()); |
|
752 | - } |
|
753 | - |
|
754 | - static::expectDateTime($date, ['null', 'string']); |
|
755 | - |
|
756 | - return $date instanceof self ? $date : static::instance($date); |
|
757 | - } |
|
758 | - |
|
759 | - /** |
|
760 | - * Return the Carbon instance passed through, a now instance in UTC |
|
761 | - * if null given or parse the input if string given (using current timezone |
|
762 | - * then switching to UTC). |
|
763 | - * |
|
764 | - * @param Carbon|DateTimeInterface|string|null $date |
|
765 | - * |
|
766 | - * @return static |
|
767 | - */ |
|
768 | - protected function resolveUTC($date = null): self |
|
769 | - { |
|
770 | - if (!$date) { |
|
771 | - return static::now('UTC'); |
|
772 | - } |
|
773 | - |
|
774 | - if (\is_string($date)) { |
|
775 | - return static::parse($date, $this->getTimezone())->utc(); |
|
776 | - } |
|
777 | - |
|
778 | - static::expectDateTime($date, ['null', 'string']); |
|
779 | - |
|
780 | - return $date instanceof self ? $date : static::instance($date)->utc(); |
|
781 | - } |
|
782 | - |
|
783 | - /** |
|
784 | - * Return the Carbon instance passed through, a now instance in the same timezone |
|
785 | - * if null given or parse the input if string given. |
|
786 | - * |
|
787 | - * @param Carbon|\Carbon\CarbonPeriod|\Carbon\CarbonInterval|\DateInterval|\DatePeriod|DateTimeInterface|string|null $date |
|
788 | - * |
|
789 | - * @return static |
|
790 | - */ |
|
791 | - public function carbonize($date = null) |
|
792 | - { |
|
793 | - if ($date instanceof DateInterval) { |
|
794 | - return $this->avoidMutation()->add($date); |
|
795 | - } |
|
796 | - |
|
797 | - if ($date instanceof DatePeriod || $date instanceof CarbonPeriod) { |
|
798 | - $date = $date->getStartDate(); |
|
799 | - } |
|
800 | - |
|
801 | - return $this->resolveCarbon($date); |
|
802 | - } |
|
803 | - |
|
804 | - /////////////////////////////////////////////////////////////////// |
|
805 | - ///////////////////////// GETTERS AND SETTERS ///////////////////// |
|
806 | - /////////////////////////////////////////////////////////////////// |
|
807 | - |
|
808 | - /** |
|
809 | - * Get a part of the Carbon object |
|
810 | - * |
|
811 | - * @param string $name |
|
812 | - * |
|
813 | - * @throws UnknownGetterException |
|
814 | - * |
|
815 | - * @return string|int|bool|DateTimeZone|null |
|
816 | - */ |
|
817 | - public function __get($name) |
|
818 | - { |
|
819 | - return $this->get($name); |
|
820 | - } |
|
821 | - |
|
822 | - /** |
|
823 | - * Get a part of the Carbon object |
|
824 | - * |
|
825 | - * @param string $name |
|
826 | - * |
|
827 | - * @throws UnknownGetterException |
|
828 | - * |
|
829 | - * @return string|int|bool|DateTimeZone|null |
|
830 | - */ |
|
831 | - public function get($name) |
|
832 | - { |
|
833 | - static $formats = [ |
|
834 | - // @property int |
|
835 | - 'year' => 'Y', |
|
836 | - // @property int |
|
837 | - 'yearIso' => 'o', |
|
838 | - // @property int |
|
839 | - // @call isSameUnit |
|
840 | - 'month' => 'n', |
|
841 | - // @property int |
|
842 | - 'day' => 'j', |
|
843 | - // @property int |
|
844 | - 'hour' => 'G', |
|
845 | - // @property int |
|
846 | - 'minute' => 'i', |
|
847 | - // @property int |
|
848 | - 'second' => 's', |
|
849 | - // @property int |
|
850 | - 'micro' => 'u', |
|
851 | - // @property int |
|
852 | - 'microsecond' => 'u', |
|
853 | - // @property-read int 0 (for Sunday) through 6 (for Saturday) |
|
854 | - 'dayOfWeek' => 'w', |
|
855 | - // @property-read int 1 (for Monday) through 7 (for Sunday) |
|
856 | - 'dayOfWeekIso' => 'N', |
|
857 | - // @property-read int ISO-8601 week number of year, weeks starting on Monday |
|
858 | - 'weekOfYear' => 'W', |
|
859 | - // @property-read int number of days in the given month |
|
860 | - 'daysInMonth' => 't', |
|
861 | - // @property int|float|string seconds since the Unix Epoch |
|
862 | - 'timestamp' => 'U', |
|
863 | - // @property-read string "am"/"pm" (Ante meridiem or Post meridiem latin lowercase mark) |
|
864 | - 'latinMeridiem' => 'a', |
|
865 | - // @property-read string "AM"/"PM" (Ante meridiem or Post meridiem latin uppercase mark) |
|
866 | - 'latinUpperMeridiem' => 'A', |
|
867 | - // @property string the day of week in English |
|
868 | - 'englishDayOfWeek' => 'l', |
|
869 | - // @property string the abbreviated day of week in English |
|
870 | - 'shortEnglishDayOfWeek' => 'D', |
|
871 | - // @property string the month in English |
|
872 | - 'englishMonth' => 'F', |
|
873 | - // @property string the abbreviated month in English |
|
874 | - 'shortEnglishMonth' => 'M', |
|
875 | - // @property string the day of week in current locale LC_TIME |
|
876 | - // @deprecated |
|
877 | - // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
878 | - // replacement: Use ->isoFormat('MMM') instead. |
|
879 | - // since: 2.55.0 |
|
880 | - 'localeDayOfWeek' => '%A', |
|
881 | - // @property string the abbreviated day of week in current locale LC_TIME |
|
882 | - // @deprecated |
|
883 | - // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
884 | - // replacement: Use ->isoFormat('dddd') instead. |
|
885 | - // since: 2.55.0 |
|
886 | - 'shortLocaleDayOfWeek' => '%a', |
|
887 | - // @property string the month in current locale LC_TIME |
|
888 | - // @deprecated |
|
889 | - // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
890 | - // replacement: Use ->isoFormat('ddd') instead. |
|
891 | - // since: 2.55.0 |
|
892 | - 'localeMonth' => '%B', |
|
893 | - // @property string the abbreviated month in current locale LC_TIME |
|
894 | - // @deprecated |
|
895 | - // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
896 | - // replacement: Use ->isoFormat('MMMM') instead. |
|
897 | - // since: 2.55.0 |
|
898 | - 'shortLocaleMonth' => '%b', |
|
899 | - // @property-read string $timezoneAbbreviatedName the current timezone abbreviated name |
|
900 | - 'timezoneAbbreviatedName' => 'T', |
|
901 | - // @property-read string $tzAbbrName alias of $timezoneAbbreviatedName |
|
902 | - 'tzAbbrName' => 'T', |
|
903 | - ]; |
|
904 | - |
|
905 | - switch (true) { |
|
906 | - case isset($formats[$name]): |
|
907 | - $format = $formats[$name]; |
|
908 | - $method = str_starts_with($format, '%') ? 'formatLocalized' : 'rawFormat'; |
|
909 | - $value = $this->$method($format); |
|
910 | - |
|
911 | - return is_numeric($value) ? (int) $value : $value; |
|
912 | - |
|
913 | - // @property-read string long name of weekday translated according to Carbon locale, in english if no translation available for current language |
|
914 | - case $name === 'dayName': |
|
915 | - return $this->getTranslatedDayName(); |
|
916 | - // @property-read string short name of weekday translated according to Carbon locale, in english if no translation available for current language |
|
917 | - case $name === 'shortDayName': |
|
918 | - return $this->getTranslatedShortDayName(); |
|
919 | - // @property-read string very short name of weekday translated according to Carbon locale, in english if no translation available for current language |
|
920 | - case $name === 'minDayName': |
|
921 | - return $this->getTranslatedMinDayName(); |
|
922 | - // @property-read string long name of month translated according to Carbon locale, in english if no translation available for current language |
|
923 | - case $name === 'monthName': |
|
924 | - return $this->getTranslatedMonthName(); |
|
925 | - // @property-read string short name of month translated according to Carbon locale, in english if no translation available for current language |
|
926 | - case $name === 'shortMonthName': |
|
927 | - return $this->getTranslatedShortMonthName(); |
|
928 | - // @property-read string lowercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language |
|
929 | - case $name === 'meridiem': |
|
930 | - return $this->meridiem(true); |
|
931 | - // @property-read string uppercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language |
|
932 | - case $name === 'upperMeridiem': |
|
933 | - return $this->meridiem(); |
|
934 | - // @property-read int current hour from 1 to 24 |
|
935 | - case $name === 'noZeroHour': |
|
936 | - return $this->hour ?: 24; |
|
937 | - // @property int |
|
938 | - case $name === 'milliseconds': |
|
939 | - // @property int |
|
940 | - case $name === 'millisecond': |
|
941 | - // @property int |
|
942 | - case $name === 'milli': |
|
943 | - return (int) floor(((int) $this->rawFormat('u')) / 1000); |
|
944 | - |
|
945 | - // @property int 1 through 53 |
|
946 | - case $name === 'week': |
|
947 | - return (int) $this->week(); |
|
948 | - |
|
949 | - // @property int 1 through 53 |
|
950 | - case $name === 'isoWeek': |
|
951 | - return (int) $this->isoWeek(); |
|
952 | - |
|
953 | - // @property int year according to week format |
|
954 | - case $name === 'weekYear': |
|
955 | - return (int) $this->weekYear(); |
|
956 | - |
|
957 | - // @property int year according to ISO week format |
|
958 | - case $name === 'isoWeekYear': |
|
959 | - return (int) $this->isoWeekYear(); |
|
960 | - |
|
961 | - // @property-read int 51 through 53 |
|
962 | - case $name === 'weeksInYear': |
|
963 | - return $this->weeksInYear(); |
|
964 | - |
|
965 | - // @property-read int 51 through 53 |
|
966 | - case $name === 'isoWeeksInYear': |
|
967 | - return $this->isoWeeksInYear(); |
|
968 | - |
|
969 | - // @property-read int 1 through 5 |
|
970 | - case $name === 'weekOfMonth': |
|
971 | - return (int) ceil($this->day / static::DAYS_PER_WEEK); |
|
972 | - |
|
973 | - // @property-read int 1 through 5 |
|
974 | - case $name === 'weekNumberInMonth': |
|
975 | - return (int) ceil(($this->day + $this->avoidMutation()->startOfMonth()->dayOfWeekIso - 1) / static::DAYS_PER_WEEK); |
|
976 | - |
|
977 | - // @property-read int 0 through 6 |
|
978 | - case $name === 'firstWeekDay': |
|
979 | - return $this->localTranslator ? ($this->getTranslationMessage('first_day_of_week') ?? 0) : static::getWeekStartsAt(); |
|
980 | - |
|
981 | - // @property-read int 0 through 6 |
|
982 | - case $name === 'lastWeekDay': |
|
983 | - return $this->localTranslator ? (($this->getTranslationMessage('first_day_of_week') ?? 0) + static::DAYS_PER_WEEK - 1) % static::DAYS_PER_WEEK : static::getWeekEndsAt(); |
|
984 | - |
|
985 | - // @property int 1 through 366 |
|
986 | - case $name === 'dayOfYear': |
|
987 | - return 1 + (int) ($this->rawFormat('z')); |
|
988 | - |
|
989 | - // @property-read int 365 or 366 |
|
990 | - case $name === 'daysInYear': |
|
991 | - return $this->isLeapYear() ? 366 : 365; |
|
992 | - |
|
993 | - // @property int does a diffInYears() with default parameters |
|
994 | - case $name === 'age': |
|
995 | - return $this->diffInYears(); |
|
996 | - |
|
997 | - // @property-read int the quarter of this instance, 1 - 4 |
|
998 | - // @call isSameUnit |
|
999 | - case $name === 'quarter': |
|
1000 | - return (int) ceil($this->month / static::MONTHS_PER_QUARTER); |
|
1001 | - |
|
1002 | - // @property-read int the decade of this instance |
|
1003 | - // @call isSameUnit |
|
1004 | - case $name === 'decade': |
|
1005 | - return (int) ceil($this->year / static::YEARS_PER_DECADE); |
|
1006 | - |
|
1007 | - // @property-read int the century of this instance |
|
1008 | - // @call isSameUnit |
|
1009 | - case $name === 'century': |
|
1010 | - $factor = 1; |
|
1011 | - $year = $this->year; |
|
1012 | - if ($year < 0) { |
|
1013 | - $year = -$year; |
|
1014 | - $factor = -1; |
|
1015 | - } |
|
1016 | - |
|
1017 | - return (int) ($factor * ceil($year / static::YEARS_PER_CENTURY)); |
|
1018 | - |
|
1019 | - // @property-read int the millennium of this instance |
|
1020 | - // @call isSameUnit |
|
1021 | - case $name === 'millennium': |
|
1022 | - $factor = 1; |
|
1023 | - $year = $this->year; |
|
1024 | - if ($year < 0) { |
|
1025 | - $year = -$year; |
|
1026 | - $factor = -1; |
|
1027 | - } |
|
1028 | - |
|
1029 | - return (int) ($factor * ceil($year / static::YEARS_PER_MILLENNIUM)); |
|
1030 | - |
|
1031 | - // @property int the timezone offset in seconds from UTC |
|
1032 | - case $name === 'offset': |
|
1033 | - return $this->getOffset(); |
|
1034 | - |
|
1035 | - // @property int the timezone offset in minutes from UTC |
|
1036 | - case $name === 'offsetMinutes': |
|
1037 | - return $this->getOffset() / static::SECONDS_PER_MINUTE; |
|
1038 | - |
|
1039 | - // @property int the timezone offset in hours from UTC |
|
1040 | - case $name === 'offsetHours': |
|
1041 | - return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR; |
|
1042 | - |
|
1043 | - // @property-read bool daylight savings time indicator, true if DST, false otherwise |
|
1044 | - case $name === 'dst': |
|
1045 | - return $this->rawFormat('I') === '1'; |
|
1046 | - |
|
1047 | - // @property-read bool checks if the timezone is local, true if local, false otherwise |
|
1048 | - case $name === 'local': |
|
1049 | - return $this->getOffset() === $this->avoidMutation()->setTimezone(date_default_timezone_get())->getOffset(); |
|
1050 | - |
|
1051 | - // @property-read bool checks if the timezone is UTC, true if UTC, false otherwise |
|
1052 | - case $name === 'utc': |
|
1053 | - return $this->getOffset() === 0; |
|
1054 | - |
|
1055 | - // @property CarbonTimeZone $timezone the current timezone |
|
1056 | - // @property CarbonTimeZone $tz alias of $timezone |
|
1057 | - case $name === 'timezone' || $name === 'tz': |
|
1058 | - return CarbonTimeZone::instance($this->getTimezone()); |
|
1059 | - |
|
1060 | - // @property-read string $timezoneName the current timezone name |
|
1061 | - // @property-read string $tzName alias of $timezoneName |
|
1062 | - case $name === 'timezoneName' || $name === 'tzName': |
|
1063 | - return $this->getTimezone()->getName(); |
|
1064 | - |
|
1065 | - // @property-read string locale of the current instance |
|
1066 | - case $name === 'locale': |
|
1067 | - return $this->getTranslatorLocale(); |
|
1068 | - |
|
1069 | - default: |
|
1070 | - $macro = $this->getLocalMacro('get'.ucfirst($name)); |
|
1071 | - |
|
1072 | - if ($macro) { |
|
1073 | - return $this->executeCallableWithContext($macro); |
|
1074 | - } |
|
1075 | - |
|
1076 | - throw new UnknownGetterException($name); |
|
1077 | - } |
|
1078 | - } |
|
1079 | - |
|
1080 | - /** |
|
1081 | - * Check if an attribute exists on the object |
|
1082 | - * |
|
1083 | - * @param string $name |
|
1084 | - * |
|
1085 | - * @return bool |
|
1086 | - */ |
|
1087 | - public function __isset($name) |
|
1088 | - { |
|
1089 | - try { |
|
1090 | - $this->__get($name); |
|
1091 | - } catch (UnknownGetterException | ReflectionException $e) { |
|
1092 | - return false; |
|
1093 | - } |
|
1094 | - |
|
1095 | - return true; |
|
1096 | - } |
|
1097 | - |
|
1098 | - /** |
|
1099 | - * Set a part of the Carbon object |
|
1100 | - * |
|
1101 | - * @param string $name |
|
1102 | - * @param string|int|DateTimeZone $value |
|
1103 | - * |
|
1104 | - * @throws UnknownSetterException|ReflectionException |
|
1105 | - * |
|
1106 | - * @return void |
|
1107 | - */ |
|
1108 | - public function __set($name, $value) |
|
1109 | - { |
|
1110 | - if ($this->constructedObjectId === spl_object_hash($this)) { |
|
1111 | - $this->set($name, $value); |
|
1112 | - |
|
1113 | - return; |
|
1114 | - } |
|
1115 | - |
|
1116 | - $this->$name = $value; |
|
1117 | - } |
|
1118 | - |
|
1119 | - /** |
|
1120 | - * Set a part of the Carbon object |
|
1121 | - * |
|
1122 | - * @param string|array $name |
|
1123 | - * @param string|int|DateTimeZone $value |
|
1124 | - * |
|
1125 | - * @throws ImmutableException|UnknownSetterException |
|
1126 | - * |
|
1127 | - * @return $this |
|
1128 | - */ |
|
1129 | - public function set($name, $value = null) |
|
1130 | - { |
|
1131 | - if ($this->isImmutable()) { |
|
1132 | - throw new ImmutableException(sprintf('%s class', static::class)); |
|
1133 | - } |
|
1134 | - |
|
1135 | - if (\is_array($name)) { |
|
1136 | - foreach ($name as $key => $value) { |
|
1137 | - $this->set($key, $value); |
|
1138 | - } |
|
1139 | - |
|
1140 | - return $this; |
|
1141 | - } |
|
1142 | - |
|
1143 | - switch ($name) { |
|
1144 | - case 'milliseconds': |
|
1145 | - case 'millisecond': |
|
1146 | - case 'milli': |
|
1147 | - case 'microseconds': |
|
1148 | - case 'microsecond': |
|
1149 | - case 'micro': |
|
1150 | - if (str_starts_with($name, 'milli')) { |
|
1151 | - $value *= 1000; |
|
1152 | - } |
|
1153 | - |
|
1154 | - while ($value < 0) { |
|
1155 | - $this->subSecond(); |
|
1156 | - $value += static::MICROSECONDS_PER_SECOND; |
|
1157 | - } |
|
1158 | - |
|
1159 | - while ($value >= static::MICROSECONDS_PER_SECOND) { |
|
1160 | - $this->addSecond(); |
|
1161 | - $value -= static::MICROSECONDS_PER_SECOND; |
|
1162 | - } |
|
1163 | - |
|
1164 | - $this->modify($this->rawFormat('H:i:s.').str_pad((string) round($value), 6, '0', STR_PAD_LEFT)); |
|
1165 | - |
|
1166 | - break; |
|
1167 | - |
|
1168 | - case 'year': |
|
1169 | - case 'month': |
|
1170 | - case 'day': |
|
1171 | - case 'hour': |
|
1172 | - case 'minute': |
|
1173 | - case 'second': |
|
1174 | - [$year, $month, $day, $hour, $minute, $second] = array_map('intval', explode('-', $this->rawFormat('Y-n-j-G-i-s'))); |
|
1175 | - $$name = $value; |
|
1176 | - $this->setDateTime($year, $month, $day, $hour, $minute, $second); |
|
1177 | - |
|
1178 | - break; |
|
1179 | - |
|
1180 | - case 'week': |
|
1181 | - $this->week($value); |
|
1182 | - |
|
1183 | - break; |
|
1184 | - |
|
1185 | - case 'isoWeek': |
|
1186 | - $this->isoWeek($value); |
|
1187 | - |
|
1188 | - break; |
|
1189 | - |
|
1190 | - case 'weekYear': |
|
1191 | - $this->weekYear($value); |
|
1192 | - |
|
1193 | - break; |
|
1194 | - |
|
1195 | - case 'isoWeekYear': |
|
1196 | - $this->isoWeekYear($value); |
|
1197 | - |
|
1198 | - break; |
|
1199 | - |
|
1200 | - case 'dayOfYear': |
|
1201 | - $this->addDays($value - $this->dayOfYear); |
|
1202 | - |
|
1203 | - break; |
|
1204 | - |
|
1205 | - case 'timestamp': |
|
1206 | - $this->setTimestamp($value); |
|
1207 | - |
|
1208 | - break; |
|
1209 | - |
|
1210 | - case 'offset': |
|
1211 | - $this->setTimezone(static::safeCreateDateTimeZone($value / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR)); |
|
1212 | - |
|
1213 | - break; |
|
1214 | - |
|
1215 | - case 'offsetMinutes': |
|
1216 | - $this->setTimezone(static::safeCreateDateTimeZone($value / static::MINUTES_PER_HOUR)); |
|
1217 | - |
|
1218 | - break; |
|
1219 | - |
|
1220 | - case 'offsetHours': |
|
1221 | - $this->setTimezone(static::safeCreateDateTimeZone($value)); |
|
1222 | - |
|
1223 | - break; |
|
1224 | - |
|
1225 | - case 'timezone': |
|
1226 | - case 'tz': |
|
1227 | - $this->setTimezone($value); |
|
1228 | - |
|
1229 | - break; |
|
1230 | - |
|
1231 | - default: |
|
1232 | - $macro = $this->getLocalMacro('set'.ucfirst($name)); |
|
1233 | - |
|
1234 | - if ($macro) { |
|
1235 | - $this->executeCallableWithContext($macro, $value); |
|
1236 | - |
|
1237 | - break; |
|
1238 | - } |
|
1239 | - |
|
1240 | - if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) { |
|
1241 | - throw new UnknownSetterException($name); |
|
1242 | - } |
|
1243 | - |
|
1244 | - $this->$name = $value; |
|
1245 | - } |
|
1246 | - |
|
1247 | - return $this; |
|
1248 | - } |
|
1249 | - |
|
1250 | - protected function getTranslatedFormByRegExp($baseKey, $keySuffix, $context, $subKey, $defaultValue) |
|
1251 | - { |
|
1252 | - $key = $baseKey.$keySuffix; |
|
1253 | - $standaloneKey = "{$key}_standalone"; |
|
1254 | - $baseTranslation = $this->getTranslationMessage($key); |
|
1255 | - |
|
1256 | - if ($baseTranslation instanceof Closure) { |
|
1257 | - return $baseTranslation($this, $context, $subKey) ?: $defaultValue; |
|
1258 | - } |
|
1259 | - |
|
1260 | - if ( |
|
1261 | - $this->getTranslationMessage("$standaloneKey.$subKey") && |
|
1262 | - (!$context || (($regExp = $this->getTranslationMessage("{$baseKey}_regexp")) && !preg_match($regExp, $context))) |
|
1263 | - ) { |
|
1264 | - $key = $standaloneKey; |
|
1265 | - } |
|
1266 | - |
|
1267 | - return $this->getTranslationMessage("$key.$subKey", null, $defaultValue); |
|
1268 | - } |
|
1269 | - |
|
1270 | - /** |
|
1271 | - * Get the translation of the current week day name (with context for languages with multiple forms). |
|
1272 | - * |
|
1273 | - * @param string|null $context whole format string |
|
1274 | - * @param string $keySuffix "", "_short" or "_min" |
|
1275 | - * @param string|null $defaultValue default value if translation missing |
|
1276 | - * |
|
1277 | - * @return string |
|
1278 | - */ |
|
1279 | - public function getTranslatedDayName($context = null, $keySuffix = '', $defaultValue = null) |
|
1280 | - { |
|
1281 | - return $this->getTranslatedFormByRegExp('weekdays', $keySuffix, $context, $this->dayOfWeek, $defaultValue ?: $this->englishDayOfWeek); |
|
1282 | - } |
|
1283 | - |
|
1284 | - /** |
|
1285 | - * Get the translation of the current short week day name (with context for languages with multiple forms). |
|
1286 | - * |
|
1287 | - * @param string|null $context whole format string |
|
1288 | - * |
|
1289 | - * @return string |
|
1290 | - */ |
|
1291 | - public function getTranslatedShortDayName($context = null) |
|
1292 | - { |
|
1293 | - return $this->getTranslatedDayName($context, '_short', $this->shortEnglishDayOfWeek); |
|
1294 | - } |
|
1295 | - |
|
1296 | - /** |
|
1297 | - * Get the translation of the current abbreviated week day name (with context for languages with multiple forms). |
|
1298 | - * |
|
1299 | - * @param string|null $context whole format string |
|
1300 | - * |
|
1301 | - * @return string |
|
1302 | - */ |
|
1303 | - public function getTranslatedMinDayName($context = null) |
|
1304 | - { |
|
1305 | - return $this->getTranslatedDayName($context, '_min', $this->shortEnglishDayOfWeek); |
|
1306 | - } |
|
1307 | - |
|
1308 | - /** |
|
1309 | - * Get the translation of the current month day name (with context for languages with multiple forms). |
|
1310 | - * |
|
1311 | - * @param string|null $context whole format string |
|
1312 | - * @param string $keySuffix "" or "_short" |
|
1313 | - * @param string|null $defaultValue default value if translation missing |
|
1314 | - * |
|
1315 | - * @return string |
|
1316 | - */ |
|
1317 | - public function getTranslatedMonthName($context = null, $keySuffix = '', $defaultValue = null) |
|
1318 | - { |
|
1319 | - return $this->getTranslatedFormByRegExp('months', $keySuffix, $context, $this->month - 1, $defaultValue ?: $this->englishMonth); |
|
1320 | - } |
|
1321 | - |
|
1322 | - /** |
|
1323 | - * Get the translation of the current short month day name (with context for languages with multiple forms). |
|
1324 | - * |
|
1325 | - * @param string|null $context whole format string |
|
1326 | - * |
|
1327 | - * @return string |
|
1328 | - */ |
|
1329 | - public function getTranslatedShortMonthName($context = null) |
|
1330 | - { |
|
1331 | - return $this->getTranslatedMonthName($context, '_short', $this->shortEnglishMonth); |
|
1332 | - } |
|
1333 | - |
|
1334 | - /** |
|
1335 | - * Get/set the day of year. |
|
1336 | - * |
|
1337 | - * @param int|null $value new value for day of year if using as setter. |
|
1338 | - * |
|
1339 | - * @return static|int |
|
1340 | - */ |
|
1341 | - public function dayOfYear($value = null) |
|
1342 | - { |
|
1343 | - $dayOfYear = $this->dayOfYear; |
|
1344 | - |
|
1345 | - return $value === null ? $dayOfYear : $this->addDays($value - $dayOfYear); |
|
1346 | - } |
|
1347 | - |
|
1348 | - /** |
|
1349 | - * Get/set the weekday from 0 (Sunday) to 6 (Saturday). |
|
1350 | - * |
|
1351 | - * @param int|null $value new value for weekday if using as setter. |
|
1352 | - * |
|
1353 | - * @return static|int |
|
1354 | - */ |
|
1355 | - public function weekday($value = null) |
|
1356 | - { |
|
1357 | - $dayOfWeek = ($this->dayOfWeek + 7 - (int) ($this->getTranslationMessage('first_day_of_week') ?? 0)) % 7; |
|
1358 | - |
|
1359 | - return $value === null ? $dayOfWeek : $this->addDays($value - $dayOfWeek); |
|
1360 | - } |
|
1361 | - |
|
1362 | - /** |
|
1363 | - * Get/set the ISO weekday from 1 (Monday) to 7 (Sunday). |
|
1364 | - * |
|
1365 | - * @param int|null $value new value for weekday if using as setter. |
|
1366 | - * |
|
1367 | - * @return static|int |
|
1368 | - */ |
|
1369 | - public function isoWeekday($value = null) |
|
1370 | - { |
|
1371 | - $dayOfWeekIso = $this->dayOfWeekIso; |
|
1372 | - |
|
1373 | - return $value === null ? $dayOfWeekIso : $this->addDays($value - $dayOfWeekIso); |
|
1374 | - } |
|
1375 | - |
|
1376 | - /** |
|
1377 | - * Set any unit to a new value without overflowing current other unit given. |
|
1378 | - * |
|
1379 | - * @param string $valueUnit unit name to modify |
|
1380 | - * @param int $value new value for the input unit |
|
1381 | - * @param string $overflowUnit unit name to not overflow |
|
1382 | - * |
|
1383 | - * @return static |
|
1384 | - */ |
|
1385 | - public function setUnitNoOverflow($valueUnit, $value, $overflowUnit) |
|
1386 | - { |
|
1387 | - try { |
|
1388 | - $original = $this->avoidMutation(); |
|
1389 | - /** @var static $date */ |
|
1390 | - $date = $this->$valueUnit($value); |
|
1391 | - $end = $original->avoidMutation()->endOf($overflowUnit); |
|
1392 | - $start = $original->avoidMutation()->startOf($overflowUnit); |
|
1393 | - if ($date < $start) { |
|
1394 | - $date = $date->setDateTimeFrom($start); |
|
1395 | - } elseif ($date > $end) { |
|
1396 | - $date = $date->setDateTimeFrom($end); |
|
1397 | - } |
|
1398 | - |
|
1399 | - return $date; |
|
1400 | - } catch (BadMethodCallException | ReflectionException $exception) { |
|
1401 | - throw new UnknownUnitException($valueUnit, 0, $exception); |
|
1402 | - } |
|
1403 | - } |
|
1404 | - |
|
1405 | - /** |
|
1406 | - * Add any unit to a new value without overflowing current other unit given. |
|
1407 | - * |
|
1408 | - * @param string $valueUnit unit name to modify |
|
1409 | - * @param int $value amount to add to the input unit |
|
1410 | - * @param string $overflowUnit unit name to not overflow |
|
1411 | - * |
|
1412 | - * @return static |
|
1413 | - */ |
|
1414 | - public function addUnitNoOverflow($valueUnit, $value, $overflowUnit) |
|
1415 | - { |
|
1416 | - return $this->setUnitNoOverflow($valueUnit, $this->$valueUnit + $value, $overflowUnit); |
|
1417 | - } |
|
1418 | - |
|
1419 | - /** |
|
1420 | - * Subtract any unit to a new value without overflowing current other unit given. |
|
1421 | - * |
|
1422 | - * @param string $valueUnit unit name to modify |
|
1423 | - * @param int $value amount to subtract to the input unit |
|
1424 | - * @param string $overflowUnit unit name to not overflow |
|
1425 | - * |
|
1426 | - * @return static |
|
1427 | - */ |
|
1428 | - public function subUnitNoOverflow($valueUnit, $value, $overflowUnit) |
|
1429 | - { |
|
1430 | - return $this->setUnitNoOverflow($valueUnit, $this->$valueUnit - $value, $overflowUnit); |
|
1431 | - } |
|
1432 | - |
|
1433 | - /** |
|
1434 | - * Returns the minutes offset to UTC if no arguments passed, else set the timezone with given minutes shift passed. |
|
1435 | - * |
|
1436 | - * @param int|null $minuteOffset |
|
1437 | - * |
|
1438 | - * @return int|static |
|
1439 | - */ |
|
1440 | - public function utcOffset(int $minuteOffset = null) |
|
1441 | - { |
|
1442 | - if (\func_num_args() < 1) { |
|
1443 | - return $this->offsetMinutes; |
|
1444 | - } |
|
1445 | - |
|
1446 | - return $this->setTimezone(CarbonTimeZone::createFromMinuteOffset($minuteOffset)); |
|
1447 | - } |
|
1448 | - |
|
1449 | - /** |
|
1450 | - * Set the date with gregorian year, month and day numbers. |
|
1451 | - * |
|
1452 | - * @see https://php.net/manual/en/datetime.setdate.php |
|
1453 | - * |
|
1454 | - * @param int $year |
|
1455 | - * @param int $month |
|
1456 | - * @param int $day |
|
1457 | - * |
|
1458 | - * @return static |
|
1459 | - */ |
|
1460 | - #[ReturnTypeWillChange] |
|
1461 | - public function setDate($year, $month, $day) |
|
1462 | - { |
|
1463 | - return parent::setDate((int) $year, (int) $month, (int) $day); |
|
1464 | - } |
|
1465 | - |
|
1466 | - /** |
|
1467 | - * Set a date according to the ISO 8601 standard - using weeks and day offsets rather than specific dates. |
|
1468 | - * |
|
1469 | - * @see https://php.net/manual/en/datetime.setisodate.php |
|
1470 | - * |
|
1471 | - * @param int $year |
|
1472 | - * @param int $week |
|
1473 | - * @param int $day |
|
1474 | - * |
|
1475 | - * @return static |
|
1476 | - */ |
|
1477 | - #[ReturnTypeWillChange] |
|
1478 | - public function setISODate($year, $week, $day = 1) |
|
1479 | - { |
|
1480 | - return parent::setISODate((int) $year, (int) $week, (int) $day); |
|
1481 | - } |
|
1482 | - |
|
1483 | - /** |
|
1484 | - * Set the date and time all together. |
|
1485 | - * |
|
1486 | - * @param int $year |
|
1487 | - * @param int $month |
|
1488 | - * @param int $day |
|
1489 | - * @param int $hour |
|
1490 | - * @param int $minute |
|
1491 | - * @param int $second |
|
1492 | - * @param int $microseconds |
|
1493 | - * |
|
1494 | - * @return static |
|
1495 | - */ |
|
1496 | - public function setDateTime($year, $month, $day, $hour, $minute, $second = 0, $microseconds = 0) |
|
1497 | - { |
|
1498 | - return $this->setDate($year, $month, $day)->setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds); |
|
1499 | - } |
|
1500 | - |
|
1501 | - /** |
|
1502 | - * Resets the current time of the DateTime object to a different time. |
|
1503 | - * |
|
1504 | - * @see https://php.net/manual/en/datetime.settime.php |
|
1505 | - * |
|
1506 | - * @param int $hour |
|
1507 | - * @param int $minute |
|
1508 | - * @param int $second |
|
1509 | - * @param int $microseconds |
|
1510 | - * |
|
1511 | - * @return static |
|
1512 | - */ |
|
1513 | - #[ReturnTypeWillChange] |
|
1514 | - public function setTime($hour, $minute, $second = 0, $microseconds = 0) |
|
1515 | - { |
|
1516 | - return parent::setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds); |
|
1517 | - } |
|
1518 | - |
|
1519 | - /** |
|
1520 | - * Set the instance's timestamp. |
|
1521 | - * |
|
1522 | - * Timestamp input can be given as int, float or a string containing one or more numbers. |
|
1523 | - * |
|
1524 | - * @param float|int|string $unixTimestamp |
|
1525 | - * |
|
1526 | - * @return static |
|
1527 | - */ |
|
1528 | - #[ReturnTypeWillChange] |
|
1529 | - public function setTimestamp($unixTimestamp) |
|
1530 | - { |
|
1531 | - [$timestamp, $microseconds] = self::getIntegerAndDecimalParts($unixTimestamp); |
|
1532 | - |
|
1533 | - return parent::setTimestamp((int) $timestamp)->setMicroseconds((int) $microseconds); |
|
1534 | - } |
|
1535 | - |
|
1536 | - /** |
|
1537 | - * Set the time by time string. |
|
1538 | - * |
|
1539 | - * @param string $time |
|
1540 | - * |
|
1541 | - * @return static |
|
1542 | - */ |
|
1543 | - public function setTimeFromTimeString($time) |
|
1544 | - { |
|
1545 | - if (!str_contains($time, ':')) { |
|
1546 | - $time .= ':0'; |
|
1547 | - } |
|
1548 | - |
|
1549 | - return $this->modify($time); |
|
1550 | - } |
|
1551 | - |
|
1552 | - /** |
|
1553 | - * @alias setTimezone |
|
1554 | - * |
|
1555 | - * @param DateTimeZone|string $value |
|
1556 | - * |
|
1557 | - * @return static |
|
1558 | - */ |
|
1559 | - public function timezone($value) |
|
1560 | - { |
|
1561 | - return $this->setTimezone($value); |
|
1562 | - } |
|
1563 | - |
|
1564 | - /** |
|
1565 | - * Set the timezone or returns the timezone name if no arguments passed. |
|
1566 | - * |
|
1567 | - * @param DateTimeZone|string $value |
|
1568 | - * |
|
1569 | - * @return static|string |
|
1570 | - */ |
|
1571 | - public function tz($value = null) |
|
1572 | - { |
|
1573 | - if (\func_num_args() < 1) { |
|
1574 | - return $this->tzName; |
|
1575 | - } |
|
1576 | - |
|
1577 | - return $this->setTimezone($value); |
|
1578 | - } |
|
1579 | - |
|
1580 | - /** |
|
1581 | - * Set the instance's timezone from a string or object. |
|
1582 | - * |
|
1583 | - * @param DateTimeZone|string $value |
|
1584 | - * |
|
1585 | - * @return static |
|
1586 | - */ |
|
1587 | - #[ReturnTypeWillChange] |
|
1588 | - public function setTimezone($value) |
|
1589 | - { |
|
1590 | - $tz = static::safeCreateDateTimeZone($value); |
|
1591 | - |
|
1592 | - if ($tz === false && !self::isStrictModeEnabled()) { |
|
1593 | - $tz = new CarbonTimeZone(); |
|
1594 | - } |
|
1595 | - |
|
1596 | - return parent::setTimezone($tz); |
|
1597 | - } |
|
1598 | - |
|
1599 | - /** |
|
1600 | - * Set the instance's timezone from a string or object and add/subtract the offset difference. |
|
1601 | - * |
|
1602 | - * @param DateTimeZone|string $value |
|
1603 | - * |
|
1604 | - * @return static |
|
1605 | - */ |
|
1606 | - public function shiftTimezone($value) |
|
1607 | - { |
|
1608 | - $dateTimeString = $this->format('Y-m-d H:i:s.u'); |
|
1609 | - |
|
1610 | - return $this |
|
1611 | - ->setTimezone($value) |
|
1612 | - ->modify($dateTimeString); |
|
1613 | - } |
|
1614 | - |
|
1615 | - /** |
|
1616 | - * Set the instance's timezone to UTC. |
|
1617 | - * |
|
1618 | - * @return static |
|
1619 | - */ |
|
1620 | - public function utc() |
|
1621 | - { |
|
1622 | - return $this->setTimezone('UTC'); |
|
1623 | - } |
|
1624 | - |
|
1625 | - /** |
|
1626 | - * Set the year, month, and date for this instance to that of the passed instance. |
|
1627 | - * |
|
1628 | - * @param Carbon|DateTimeInterface $date now if null |
|
1629 | - * |
|
1630 | - * @return static |
|
1631 | - */ |
|
1632 | - public function setDateFrom($date = null) |
|
1633 | - { |
|
1634 | - $date = $this->resolveCarbon($date); |
|
1635 | - |
|
1636 | - return $this->setDate($date->year, $date->month, $date->day); |
|
1637 | - } |
|
1638 | - |
|
1639 | - /** |
|
1640 | - * Set the hour, minute, second and microseconds for this instance to that of the passed instance. |
|
1641 | - * |
|
1642 | - * @param Carbon|DateTimeInterface $date now if null |
|
1643 | - * |
|
1644 | - * @return static |
|
1645 | - */ |
|
1646 | - public function setTimeFrom($date = null) |
|
1647 | - { |
|
1648 | - $date = $this->resolveCarbon($date); |
|
1649 | - |
|
1650 | - return $this->setTime($date->hour, $date->minute, $date->second, $date->microsecond); |
|
1651 | - } |
|
1652 | - |
|
1653 | - /** |
|
1654 | - * Set the date and time for this instance to that of the passed instance. |
|
1655 | - * |
|
1656 | - * @param Carbon|DateTimeInterface $date |
|
1657 | - * |
|
1658 | - * @return static |
|
1659 | - */ |
|
1660 | - public function setDateTimeFrom($date = null) |
|
1661 | - { |
|
1662 | - $date = $this->resolveCarbon($date); |
|
1663 | - |
|
1664 | - return $this->modify($date->rawFormat('Y-m-d H:i:s.u')); |
|
1665 | - } |
|
1666 | - |
|
1667 | - /** |
|
1668 | - * Get the days of the week |
|
1669 | - * |
|
1670 | - * @return array |
|
1671 | - */ |
|
1672 | - public static function getDays() |
|
1673 | - { |
|
1674 | - return static::$days; |
|
1675 | - } |
|
1676 | - |
|
1677 | - /////////////////////////////////////////////////////////////////// |
|
1678 | - /////////////////////// WEEK SPECIAL DAYS ///////////////////////// |
|
1679 | - /////////////////////////////////////////////////////////////////// |
|
1680 | - |
|
1681 | - private static function getFirstDayOfWeek(): int |
|
1682 | - { |
|
1683 | - return (int) static::getTranslationMessageWith( |
|
1684 | - static::getTranslator(), |
|
1685 | - 'first_day_of_week' |
|
1686 | - ); |
|
1687 | - } |
|
1688 | - |
|
1689 | - /** |
|
1690 | - * Get the first day of week |
|
1691 | - * |
|
1692 | - * @return int |
|
1693 | - */ |
|
1694 | - public static function getWeekStartsAt() |
|
1695 | - { |
|
1696 | - if (static::$weekStartsAt === static::WEEK_DAY_AUTO) { |
|
1697 | - return self::getFirstDayOfWeek(); |
|
1698 | - } |
|
1699 | - |
|
1700 | - return static::$weekStartsAt; |
|
1701 | - } |
|
1702 | - |
|
1703 | - /** |
|
1704 | - * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
1705 | - * Use $weekEndsAt optional parameter instead when using endOfWeek method. You can also use the |
|
1706 | - * 'first_day_of_week' locale setting to change the start of week according to current locale |
|
1707 | - * selected and implicitly the end of week. |
|
1708 | - * |
|
1709 | - * Set the first day of week |
|
1710 | - * |
|
1711 | - * @param int|string $day week start day (or 'auto' to get the first day of week from Carbon::getLocale() culture). |
|
1712 | - * |
|
1713 | - * @return void |
|
1714 | - */ |
|
1715 | - public static function setWeekStartsAt($day) |
|
1716 | - { |
|
1717 | - static::$weekStartsAt = $day === static::WEEK_DAY_AUTO ? $day : max(0, (7 + $day) % 7); |
|
1718 | - } |
|
1719 | - |
|
1720 | - /** |
|
1721 | - * Get the last day of week |
|
1722 | - * |
|
1723 | - * @return int |
|
1724 | - */ |
|
1725 | - public static function getWeekEndsAt() |
|
1726 | - { |
|
1727 | - if (static::$weekStartsAt === static::WEEK_DAY_AUTO) { |
|
1728 | - return (int) (static::DAYS_PER_WEEK - 1 + self::getFirstDayOfWeek()) % static::DAYS_PER_WEEK; |
|
1729 | - } |
|
1730 | - |
|
1731 | - return static::$weekEndsAt; |
|
1732 | - } |
|
1733 | - |
|
1734 | - /** |
|
1735 | - * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
1736 | - * Use $weekStartsAt optional parameter instead when using startOfWeek, floorWeek, ceilWeek |
|
1737 | - * or roundWeek method. You can also use the 'first_day_of_week' locale setting to change the |
|
1738 | - * start of week according to current locale selected and implicitly the end of week. |
|
1739 | - * |
|
1740 | - * Set the last day of week |
|
1741 | - * |
|
1742 | - * @param int|string $day week end day (or 'auto' to get the day before the first day of week |
|
1743 | - * from Carbon::getLocale() culture). |
|
1744 | - * |
|
1745 | - * @return void |
|
1746 | - */ |
|
1747 | - public static function setWeekEndsAt($day) |
|
1748 | - { |
|
1749 | - static::$weekEndsAt = $day === static::WEEK_DAY_AUTO ? $day : max(0, (7 + $day) % 7); |
|
1750 | - } |
|
1751 | - |
|
1752 | - /** |
|
1753 | - * Get weekend days |
|
1754 | - * |
|
1755 | - * @return array |
|
1756 | - */ |
|
1757 | - public static function getWeekendDays() |
|
1758 | - { |
|
1759 | - return static::$weekendDays; |
|
1760 | - } |
|
1761 | - |
|
1762 | - /** |
|
1763 | - * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
1764 | - * You should rather consider week-end is always saturday and sunday, and if you have some custom |
|
1765 | - * week-end days to handle, give to those days an other name and create a macro for them: |
|
1766 | - * |
|
1767 | - * ``` |
|
1768 | - * Carbon::macro('isDayOff', function ($date) { |
|
1769 | - * return $date->isSunday() || $date->isMonday(); |
|
1770 | - * }); |
|
1771 | - * Carbon::macro('isNotDayOff', function ($date) { |
|
1772 | - * return !$date->isDayOff(); |
|
1773 | - * }); |
|
1774 | - * if ($someDate->isDayOff()) ... |
|
1775 | - * if ($someDate->isNotDayOff()) ... |
|
1776 | - * // Add 5 not-off days |
|
1777 | - * $count = 5; |
|
1778 | - * while ($someDate->isDayOff() || ($count-- > 0)) { |
|
1779 | - * $someDate->addDay(); |
|
1780 | - * } |
|
1781 | - * ``` |
|
1782 | - * |
|
1783 | - * Set weekend days |
|
1784 | - * |
|
1785 | - * @param array $days |
|
1786 | - * |
|
1787 | - * @return void |
|
1788 | - */ |
|
1789 | - public static function setWeekendDays($days) |
|
1790 | - { |
|
1791 | - static::$weekendDays = $days; |
|
1792 | - } |
|
1793 | - |
|
1794 | - /** |
|
1795 | - * Determine if a time string will produce a relative date. |
|
1796 | - * |
|
1797 | - * @param string $time |
|
1798 | - * |
|
1799 | - * @return bool true if time match a relative date, false if absolute or invalid time string |
|
1800 | - */ |
|
1801 | - public static function hasRelativeKeywords($time) |
|
1802 | - { |
|
1803 | - if (!$time || strtotime($time) === false) { |
|
1804 | - return false; |
|
1805 | - } |
|
1806 | - |
|
1807 | - $date1 = new DateTime('2000-01-01T00:00:00Z'); |
|
1808 | - $date1->modify($time); |
|
1809 | - $date2 = new DateTime('2001-12-25T00:00:00Z'); |
|
1810 | - $date2->modify($time); |
|
1811 | - |
|
1812 | - return $date1 != $date2; |
|
1813 | - } |
|
1814 | - |
|
1815 | - /////////////////////////////////////////////////////////////////// |
|
1816 | - /////////////////////// STRING FORMATTING ///////////////////////// |
|
1817 | - /////////////////////////////////////////////////////////////////// |
|
1818 | - |
|
1819 | - /** |
|
1820 | - * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
1821 | - * You should rather use UTF-8 language packages on every machine. |
|
1822 | - * |
|
1823 | - * Set if UTF8 will be used for localized date/time. |
|
1824 | - * |
|
1825 | - * @param bool $utf8 |
|
1826 | - */ |
|
1827 | - public static function setUtf8($utf8) |
|
1828 | - { |
|
1829 | - static::$utf8 = $utf8; |
|
1830 | - } |
|
1831 | - |
|
1832 | - /** |
|
1833 | - * Format the instance with the current locale. You can set the current |
|
1834 | - * locale using setlocale() https://php.net/setlocale. |
|
1835 | - * |
|
1836 | - * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
1837 | - * Use ->isoFormat() instead. |
|
1838 | - * Deprecated since 2.55.0 |
|
1839 | - * |
|
1840 | - * @param string $format |
|
1841 | - * |
|
1842 | - * @return string |
|
1843 | - */ |
|
1844 | - public function formatLocalized($format) |
|
1845 | - { |
|
1846 | - // Check for Windows to find and replace the %e modifier correctly. |
|
1847 | - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { |
|
1848 | - $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format); // @codeCoverageIgnore |
|
1849 | - } |
|
1850 | - |
|
1851 | - $time = strtotime($this->toDateTimeString()); |
|
1852 | - $formatted = ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) |
|
1853 | - ? strftime($format, $time) |
|
1854 | - : @strftime($format, $time); |
|
1855 | - |
|
1856 | - return static::$utf8 |
|
1857 | - ? ( |
|
1858 | - \function_exists('mb_convert_encoding') |
|
1859 | - ? mb_convert_encoding($formatted, 'UTF-8', mb_list_encodings()) |
|
1860 | - : mb_convert_encoding($formatted, 'UTF-8', 'ISO-8859-1') |
|
1861 | - ) |
|
1862 | - : $formatted; |
|
1863 | - } |
|
1864 | - |
|
1865 | - /** |
|
1866 | - * Returns list of locale formats for ISO formatting. |
|
1867 | - * |
|
1868 | - * @param string|null $locale current locale used if null |
|
1869 | - * |
|
1870 | - * @return array |
|
1871 | - */ |
|
1872 | - public function getIsoFormats($locale = null) |
|
1873 | - { |
|
1874 | - return [ |
|
1875 | - 'LT' => $this->getTranslationMessage('formats.LT', $locale, 'h:mm A'), |
|
1876 | - 'LTS' => $this->getTranslationMessage('formats.LTS', $locale, 'h:mm:ss A'), |
|
1877 | - 'L' => $this->getTranslationMessage('formats.L', $locale, 'MM/DD/YYYY'), |
|
1878 | - 'LL' => $this->getTranslationMessage('formats.LL', $locale, 'MMMM D, YYYY'), |
|
1879 | - 'LLL' => $this->getTranslationMessage('formats.LLL', $locale, 'MMMM D, YYYY h:mm A'), |
|
1880 | - 'LLLL' => $this->getTranslationMessage('formats.LLLL', $locale, 'dddd, MMMM D, YYYY h:mm A'), |
|
1881 | - ]; |
|
1882 | - } |
|
1883 | - |
|
1884 | - /** |
|
1885 | - * Returns list of calendar formats for ISO formatting. |
|
1886 | - * |
|
1887 | - * @param string|null $locale current locale used if null |
|
1888 | - * |
|
1889 | - * @return array |
|
1890 | - */ |
|
1891 | - public function getCalendarFormats($locale = null) |
|
1892 | - { |
|
1893 | - return [ |
|
1894 | - 'sameDay' => $this->getTranslationMessage('calendar.sameDay', $locale, '[Today at] LT'), |
|
1895 | - 'nextDay' => $this->getTranslationMessage('calendar.nextDay', $locale, '[Tomorrow at] LT'), |
|
1896 | - 'nextWeek' => $this->getTranslationMessage('calendar.nextWeek', $locale, 'dddd [at] LT'), |
|
1897 | - 'lastDay' => $this->getTranslationMessage('calendar.lastDay', $locale, '[Yesterday at] LT'), |
|
1898 | - 'lastWeek' => $this->getTranslationMessage('calendar.lastWeek', $locale, '[Last] dddd [at] LT'), |
|
1899 | - 'sameElse' => $this->getTranslationMessage('calendar.sameElse', $locale, 'L'), |
|
1900 | - ]; |
|
1901 | - } |
|
1902 | - |
|
1903 | - /** |
|
1904 | - * Returns list of locale units for ISO formatting. |
|
1905 | - * |
|
1906 | - * @return array |
|
1907 | - */ |
|
1908 | - public static function getIsoUnits() |
|
1909 | - { |
|
1910 | - static $units = null; |
|
1911 | - |
|
1912 | - if ($units === null) { |
|
1913 | - $units = [ |
|
1914 | - 'OD' => ['getAltNumber', ['day']], |
|
1915 | - 'OM' => ['getAltNumber', ['month']], |
|
1916 | - 'OY' => ['getAltNumber', ['year']], |
|
1917 | - 'OH' => ['getAltNumber', ['hour']], |
|
1918 | - 'Oh' => ['getAltNumber', ['h']], |
|
1919 | - 'Om' => ['getAltNumber', ['minute']], |
|
1920 | - 'Os' => ['getAltNumber', ['second']], |
|
1921 | - 'D' => 'day', |
|
1922 | - 'DD' => ['rawFormat', ['d']], |
|
1923 | - 'Do' => ['ordinal', ['day', 'D']], |
|
1924 | - 'd' => 'dayOfWeek', |
|
1925 | - 'dd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1926 | - return $date->getTranslatedMinDayName($originalFormat); |
|
1927 | - }, |
|
1928 | - 'ddd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1929 | - return $date->getTranslatedShortDayName($originalFormat); |
|
1930 | - }, |
|
1931 | - 'dddd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1932 | - return $date->getTranslatedDayName($originalFormat); |
|
1933 | - }, |
|
1934 | - 'DDD' => 'dayOfYear', |
|
1935 | - 'DDDD' => ['getPaddedUnit', ['dayOfYear', 3]], |
|
1936 | - 'DDDo' => ['ordinal', ['dayOfYear', 'DDD']], |
|
1937 | - 'e' => ['weekday', []], |
|
1938 | - 'E' => 'dayOfWeekIso', |
|
1939 | - 'H' => ['rawFormat', ['G']], |
|
1940 | - 'HH' => ['rawFormat', ['H']], |
|
1941 | - 'h' => ['rawFormat', ['g']], |
|
1942 | - 'hh' => ['rawFormat', ['h']], |
|
1943 | - 'k' => 'noZeroHour', |
|
1944 | - 'kk' => ['getPaddedUnit', ['noZeroHour']], |
|
1945 | - 'hmm' => ['rawFormat', ['gi']], |
|
1946 | - 'hmmss' => ['rawFormat', ['gis']], |
|
1947 | - 'Hmm' => ['rawFormat', ['Gi']], |
|
1948 | - 'Hmmss' => ['rawFormat', ['Gis']], |
|
1949 | - 'm' => 'minute', |
|
1950 | - 'mm' => ['rawFormat', ['i']], |
|
1951 | - 'a' => 'meridiem', |
|
1952 | - 'A' => 'upperMeridiem', |
|
1953 | - 's' => 'second', |
|
1954 | - 'ss' => ['getPaddedUnit', ['second']], |
|
1955 | - 'S' => function (CarbonInterface $date) { |
|
1956 | - return (string) floor($date->micro / 100000); |
|
1957 | - }, |
|
1958 | - 'SS' => function (CarbonInterface $date) { |
|
1959 | - return str_pad((string) floor($date->micro / 10000), 2, '0', STR_PAD_LEFT); |
|
1960 | - }, |
|
1961 | - 'SSS' => function (CarbonInterface $date) { |
|
1962 | - return str_pad((string) floor($date->micro / 1000), 3, '0', STR_PAD_LEFT); |
|
1963 | - }, |
|
1964 | - 'SSSS' => function (CarbonInterface $date) { |
|
1965 | - return str_pad((string) floor($date->micro / 100), 4, '0', STR_PAD_LEFT); |
|
1966 | - }, |
|
1967 | - 'SSSSS' => function (CarbonInterface $date) { |
|
1968 | - return str_pad((string) floor($date->micro / 10), 5, '0', STR_PAD_LEFT); |
|
1969 | - }, |
|
1970 | - 'SSSSSS' => ['getPaddedUnit', ['micro', 6]], |
|
1971 | - 'SSSSSSS' => function (CarbonInterface $date) { |
|
1972 | - return str_pad((string) floor($date->micro * 10), 7, '0', STR_PAD_LEFT); |
|
1973 | - }, |
|
1974 | - 'SSSSSSSS' => function (CarbonInterface $date) { |
|
1975 | - return str_pad((string) floor($date->micro * 100), 8, '0', STR_PAD_LEFT); |
|
1976 | - }, |
|
1977 | - 'SSSSSSSSS' => function (CarbonInterface $date) { |
|
1978 | - return str_pad((string) floor($date->micro * 1000), 9, '0', STR_PAD_LEFT); |
|
1979 | - }, |
|
1980 | - 'M' => 'month', |
|
1981 | - 'MM' => ['rawFormat', ['m']], |
|
1982 | - 'MMM' => function (CarbonInterface $date, $originalFormat = null) { |
|
1983 | - $month = $date->getTranslatedShortMonthName($originalFormat); |
|
1984 | - $suffix = $date->getTranslationMessage('mmm_suffix'); |
|
1985 | - if ($suffix && $month !== $date->monthName) { |
|
1986 | - $month .= $suffix; |
|
1987 | - } |
|
1988 | - |
|
1989 | - return $month; |
|
1990 | - }, |
|
1991 | - 'MMMM' => function (CarbonInterface $date, $originalFormat = null) { |
|
1992 | - return $date->getTranslatedMonthName($originalFormat); |
|
1993 | - }, |
|
1994 | - 'Mo' => ['ordinal', ['month', 'M']], |
|
1995 | - 'Q' => 'quarter', |
|
1996 | - 'Qo' => ['ordinal', ['quarter', 'M']], |
|
1997 | - 'G' => 'isoWeekYear', |
|
1998 | - 'GG' => ['getPaddedUnit', ['isoWeekYear']], |
|
1999 | - 'GGG' => ['getPaddedUnit', ['isoWeekYear', 3]], |
|
2000 | - 'GGGG' => ['getPaddedUnit', ['isoWeekYear', 4]], |
|
2001 | - 'GGGGG' => ['getPaddedUnit', ['isoWeekYear', 5]], |
|
2002 | - 'g' => 'weekYear', |
|
2003 | - 'gg' => ['getPaddedUnit', ['weekYear']], |
|
2004 | - 'ggg' => ['getPaddedUnit', ['weekYear', 3]], |
|
2005 | - 'gggg' => ['getPaddedUnit', ['weekYear', 4]], |
|
2006 | - 'ggggg' => ['getPaddedUnit', ['weekYear', 5]], |
|
2007 | - 'W' => 'isoWeek', |
|
2008 | - 'WW' => ['getPaddedUnit', ['isoWeek']], |
|
2009 | - 'Wo' => ['ordinal', ['isoWeek', 'W']], |
|
2010 | - 'w' => 'week', |
|
2011 | - 'ww' => ['getPaddedUnit', ['week']], |
|
2012 | - 'wo' => ['ordinal', ['week', 'w']], |
|
2013 | - 'x' => ['valueOf', []], |
|
2014 | - 'X' => 'timestamp', |
|
2015 | - 'Y' => 'year', |
|
2016 | - 'YY' => ['rawFormat', ['y']], |
|
2017 | - 'YYYY' => ['getPaddedUnit', ['year', 4]], |
|
2018 | - 'YYYYY' => ['getPaddedUnit', ['year', 5]], |
|
2019 | - 'YYYYYY' => function (CarbonInterface $date) { |
|
2020 | - return ($date->year < 0 ? '' : '+').$date->getPaddedUnit('year', 6); |
|
2021 | - }, |
|
2022 | - 'z' => ['rawFormat', ['T']], |
|
2023 | - 'zz' => 'tzName', |
|
2024 | - 'Z' => ['getOffsetString', []], |
|
2025 | - 'ZZ' => ['getOffsetString', ['']], |
|
2026 | - ]; |
|
2027 | - } |
|
2028 | - |
|
2029 | - return $units; |
|
2030 | - } |
|
2031 | - |
|
2032 | - /** |
|
2033 | - * Returns a unit of the instance padded with 0 by default or any other string if specified. |
|
2034 | - * |
|
2035 | - * @param string $unit Carbon unit name |
|
2036 | - * @param int $length Length of the output (2 by default) |
|
2037 | - * @param string $padString String to use for padding ("0" by default) |
|
2038 | - * @param int $padType Side(s) to pad (STR_PAD_LEFT by default) |
|
2039 | - * |
|
2040 | - * @return string |
|
2041 | - */ |
|
2042 | - public function getPaddedUnit($unit, $length = 2, $padString = '0', $padType = STR_PAD_LEFT) |
|
2043 | - { |
|
2044 | - return ($this->$unit < 0 ? '-' : '').str_pad((string) abs($this->$unit), $length, $padString, $padType); |
|
2045 | - } |
|
2046 | - |
|
2047 | - /** |
|
2048 | - * Return a property with its ordinal. |
|
2049 | - * |
|
2050 | - * @param string $key |
|
2051 | - * @param string|null $period |
|
2052 | - * |
|
2053 | - * @return string |
|
2054 | - */ |
|
2055 | - public function ordinal(string $key, ?string $period = null): string |
|
2056 | - { |
|
2057 | - $number = $this->$key; |
|
2058 | - $result = $this->translate('ordinal', [ |
|
2059 | - ':number' => $number, |
|
2060 | - ':period' => (string) $period, |
|
2061 | - ]); |
|
2062 | - |
|
2063 | - return (string) ($result === 'ordinal' ? $number : $result); |
|
2064 | - } |
|
2065 | - |
|
2066 | - /** |
|
2067 | - * Return the meridiem of the current time in the current locale. |
|
2068 | - * |
|
2069 | - * @param bool $isLower if true, returns lowercase variant if available in the current locale. |
|
2070 | - * |
|
2071 | - * @return string |
|
2072 | - */ |
|
2073 | - public function meridiem(bool $isLower = false): string |
|
2074 | - { |
|
2075 | - $hour = $this->hour; |
|
2076 | - $index = $hour < 12 ? 0 : 1; |
|
2077 | - |
|
2078 | - if ($isLower) { |
|
2079 | - $key = 'meridiem.'.($index + 2); |
|
2080 | - $result = $this->translate($key); |
|
2081 | - |
|
2082 | - if ($result !== $key) { |
|
2083 | - return $result; |
|
2084 | - } |
|
2085 | - } |
|
2086 | - |
|
2087 | - $key = "meridiem.$index"; |
|
2088 | - $result = $this->translate($key); |
|
2089 | - if ($result === $key) { |
|
2090 | - $result = $this->translate('meridiem', [ |
|
2091 | - ':hour' => $this->hour, |
|
2092 | - ':minute' => $this->minute, |
|
2093 | - ':isLower' => $isLower, |
|
2094 | - ]); |
|
2095 | - |
|
2096 | - if ($result === 'meridiem') { |
|
2097 | - return $isLower ? $this->latinMeridiem : $this->latinUpperMeridiem; |
|
2098 | - } |
|
2099 | - } elseif ($isLower) { |
|
2100 | - $result = mb_strtolower($result); |
|
2101 | - } |
|
2102 | - |
|
2103 | - return $result; |
|
2104 | - } |
|
2105 | - |
|
2106 | - /** |
|
2107 | - * Returns the alternative number for a given date property if available in the current locale. |
|
2108 | - * |
|
2109 | - * @param string $key date property |
|
2110 | - * |
|
2111 | - * @return string |
|
2112 | - */ |
|
2113 | - public function getAltNumber(string $key): string |
|
2114 | - { |
|
2115 | - return $this->translateNumber(\strlen($key) > 1 ? $this->$key : $this->rawFormat('h')); |
|
2116 | - } |
|
2117 | - |
|
2118 | - /** |
|
2119 | - * Format in the current language using ISO replacement patterns. |
|
2120 | - * |
|
2121 | - * @param string $format |
|
2122 | - * @param string|null $originalFormat provide context if a chunk has been passed alone |
|
2123 | - * |
|
2124 | - * @return string |
|
2125 | - */ |
|
2126 | - public function isoFormat(string $format, ?string $originalFormat = null): string |
|
2127 | - { |
|
2128 | - $result = ''; |
|
2129 | - $length = mb_strlen($format); |
|
2130 | - $originalFormat = $originalFormat ?: $format; |
|
2131 | - $inEscaped = false; |
|
2132 | - $formats = null; |
|
2133 | - $units = null; |
|
2134 | - |
|
2135 | - for ($i = 0; $i < $length; $i++) { |
|
2136 | - $char = mb_substr($format, $i, 1); |
|
2137 | - |
|
2138 | - if ($char === '\\') { |
|
2139 | - $result .= mb_substr($format, ++$i, 1); |
|
2140 | - |
|
2141 | - continue; |
|
2142 | - } |
|
2143 | - |
|
2144 | - if ($char === '[' && !$inEscaped) { |
|
2145 | - $inEscaped = true; |
|
2146 | - |
|
2147 | - continue; |
|
2148 | - } |
|
2149 | - |
|
2150 | - if ($char === ']' && $inEscaped) { |
|
2151 | - $inEscaped = false; |
|
2152 | - |
|
2153 | - continue; |
|
2154 | - } |
|
2155 | - |
|
2156 | - if ($inEscaped) { |
|
2157 | - $result .= $char; |
|
2158 | - |
|
2159 | - continue; |
|
2160 | - } |
|
2161 | - |
|
2162 | - $input = mb_substr($format, $i); |
|
2163 | - |
|
2164 | - if (preg_match('/^(LTS|LT|[Ll]{1,4})/', $input, $match)) { |
|
2165 | - if ($formats === null) { |
|
2166 | - $formats = $this->getIsoFormats(); |
|
2167 | - } |
|
2168 | - |
|
2169 | - $code = $match[0]; |
|
2170 | - $sequence = $formats[$code] ?? preg_replace_callback( |
|
2171 | - '/MMMM|MM|DD|dddd/', |
|
2172 | - function ($code) { |
|
2173 | - return mb_substr($code[0], 1); |
|
2174 | - }, |
|
2175 | - $formats[strtoupper($code)] ?? '' |
|
2176 | - ); |
|
2177 | - $rest = mb_substr($format, $i + mb_strlen($code)); |
|
2178 | - $format = mb_substr($format, 0, $i).$sequence.$rest; |
|
2179 | - $length = mb_strlen($format); |
|
2180 | - $input = $sequence.$rest; |
|
2181 | - } |
|
2182 | - |
|
2183 | - if (preg_match('/^'.CarbonInterface::ISO_FORMAT_REGEXP.'/', $input, $match)) { |
|
2184 | - $code = $match[0]; |
|
2185 | - |
|
2186 | - if ($units === null) { |
|
2187 | - $units = static::getIsoUnits(); |
|
2188 | - } |
|
2189 | - |
|
2190 | - $sequence = $units[$code] ?? ''; |
|
2191 | - |
|
2192 | - if ($sequence instanceof Closure) { |
|
2193 | - $sequence = $sequence($this, $originalFormat); |
|
2194 | - } elseif (\is_array($sequence)) { |
|
2195 | - try { |
|
2196 | - $sequence = $this->{$sequence[0]}(...$sequence[1]); |
|
2197 | - } catch (ReflectionException | InvalidArgumentException | BadMethodCallException $e) { |
|
2198 | - $sequence = ''; |
|
2199 | - } |
|
2200 | - } elseif (\is_string($sequence)) { |
|
2201 | - $sequence = $this->$sequence ?? $code; |
|
2202 | - } |
|
2203 | - |
|
2204 | - $format = mb_substr($format, 0, $i).$sequence.mb_substr($format, $i + mb_strlen($code)); |
|
2205 | - $i += mb_strlen((string) $sequence) - 1; |
|
2206 | - $length = mb_strlen($format); |
|
2207 | - $char = $sequence; |
|
2208 | - } |
|
2209 | - |
|
2210 | - $result .= $char; |
|
2211 | - } |
|
2212 | - |
|
2213 | - return $result; |
|
2214 | - } |
|
2215 | - |
|
2216 | - /** |
|
2217 | - * List of replacements from date() format to isoFormat(). |
|
2218 | - * |
|
2219 | - * @return array |
|
2220 | - */ |
|
2221 | - public static function getFormatsToIsoReplacements() |
|
2222 | - { |
|
2223 | - static $replacements = null; |
|
2224 | - |
|
2225 | - if ($replacements === null) { |
|
2226 | - $replacements = [ |
|
2227 | - 'd' => true, |
|
2228 | - 'D' => 'ddd', |
|
2229 | - 'j' => true, |
|
2230 | - 'l' => 'dddd', |
|
2231 | - 'N' => true, |
|
2232 | - 'S' => function ($date) { |
|
2233 | - $day = $date->rawFormat('j'); |
|
2234 | - |
|
2235 | - return str_replace((string) $day, '', $date->isoFormat('Do')); |
|
2236 | - }, |
|
2237 | - 'w' => true, |
|
2238 | - 'z' => true, |
|
2239 | - 'W' => true, |
|
2240 | - 'F' => 'MMMM', |
|
2241 | - 'm' => true, |
|
2242 | - 'M' => 'MMM', |
|
2243 | - 'n' => true, |
|
2244 | - 't' => true, |
|
2245 | - 'L' => true, |
|
2246 | - 'o' => true, |
|
2247 | - 'Y' => true, |
|
2248 | - 'y' => true, |
|
2249 | - 'a' => 'a', |
|
2250 | - 'A' => 'A', |
|
2251 | - 'B' => true, |
|
2252 | - 'g' => true, |
|
2253 | - 'G' => true, |
|
2254 | - 'h' => true, |
|
2255 | - 'H' => true, |
|
2256 | - 'i' => true, |
|
2257 | - 's' => true, |
|
2258 | - 'u' => true, |
|
2259 | - 'v' => true, |
|
2260 | - 'E' => true, |
|
2261 | - 'I' => true, |
|
2262 | - 'O' => true, |
|
2263 | - 'P' => true, |
|
2264 | - 'Z' => true, |
|
2265 | - 'c' => true, |
|
2266 | - 'r' => true, |
|
2267 | - 'U' => true, |
|
2268 | - ]; |
|
2269 | - } |
|
2270 | - |
|
2271 | - return $replacements; |
|
2272 | - } |
|
2273 | - |
|
2274 | - /** |
|
2275 | - * Format as ->format() do (using date replacements patterns from https://php.net/manual/en/function.date.php) |
|
2276 | - * but translate words whenever possible (months, day names, etc.) using the current locale. |
|
2277 | - * |
|
2278 | - * @param string $format |
|
2279 | - * |
|
2280 | - * @return string |
|
2281 | - */ |
|
2282 | - public function translatedFormat(string $format): string |
|
2283 | - { |
|
2284 | - $replacements = static::getFormatsToIsoReplacements(); |
|
2285 | - $context = ''; |
|
2286 | - $isoFormat = ''; |
|
2287 | - $length = mb_strlen($format); |
|
2288 | - |
|
2289 | - for ($i = 0; $i < $length; $i++) { |
|
2290 | - $char = mb_substr($format, $i, 1); |
|
2291 | - |
|
2292 | - if ($char === '\\') { |
|
2293 | - $replacement = mb_substr($format, $i, 2); |
|
2294 | - $isoFormat .= $replacement; |
|
2295 | - $i++; |
|
2296 | - |
|
2297 | - continue; |
|
2298 | - } |
|
2299 | - |
|
2300 | - if (!isset($replacements[$char])) { |
|
2301 | - $replacement = preg_match('/^[A-Za-z]$/', $char) ? "\\$char" : $char; |
|
2302 | - $isoFormat .= $replacement; |
|
2303 | - $context .= $replacement; |
|
2304 | - |
|
2305 | - continue; |
|
2306 | - } |
|
2307 | - |
|
2308 | - $replacement = $replacements[$char]; |
|
2309 | - |
|
2310 | - if ($replacement === true) { |
|
2311 | - static $contextReplacements = null; |
|
2312 | - |
|
2313 | - if ($contextReplacements === null) { |
|
2314 | - $contextReplacements = [ |
|
2315 | - 'm' => 'MM', |
|
2316 | - 'd' => 'DD', |
|
2317 | - 't' => 'D', |
|
2318 | - 'j' => 'D', |
|
2319 | - 'N' => 'e', |
|
2320 | - 'w' => 'e', |
|
2321 | - 'n' => 'M', |
|
2322 | - 'o' => 'YYYY', |
|
2323 | - 'Y' => 'YYYY', |
|
2324 | - 'y' => 'YY', |
|
2325 | - 'g' => 'h', |
|
2326 | - 'G' => 'H', |
|
2327 | - 'h' => 'hh', |
|
2328 | - 'H' => 'HH', |
|
2329 | - 'i' => 'mm', |
|
2330 | - 's' => 'ss', |
|
2331 | - ]; |
|
2332 | - } |
|
2333 | - |
|
2334 | - $isoFormat .= '['.$this->rawFormat($char).']'; |
|
2335 | - $context .= $contextReplacements[$char] ?? ' '; |
|
2336 | - |
|
2337 | - continue; |
|
2338 | - } |
|
2339 | - |
|
2340 | - if ($replacement instanceof Closure) { |
|
2341 | - $replacement = '['.$replacement($this).']'; |
|
2342 | - $isoFormat .= $replacement; |
|
2343 | - $context .= $replacement; |
|
2344 | - |
|
2345 | - continue; |
|
2346 | - } |
|
2347 | - |
|
2348 | - $isoFormat .= $replacement; |
|
2349 | - $context .= $replacement; |
|
2350 | - } |
|
2351 | - |
|
2352 | - return $this->isoFormat($isoFormat, $context); |
|
2353 | - } |
|
2354 | - |
|
2355 | - /** |
|
2356 | - * Returns the offset hour and minute formatted with +/- and a given separator (":" by default). |
|
2357 | - * For example, if the time zone is 9 hours 30 minutes, you'll get "+09:30", with "@@" as first |
|
2358 | - * argument, "+09@@30", with "" as first argument, "+0930". Negative offset will return something |
|
2359 | - * like "-12:00". |
|
2360 | - * |
|
2361 | - * @param string $separator string to place between hours and minutes (":" by default) |
|
2362 | - * |
|
2363 | - * @return string |
|
2364 | - */ |
|
2365 | - public function getOffsetString($separator = ':') |
|
2366 | - { |
|
2367 | - $second = $this->getOffset(); |
|
2368 | - $symbol = $second < 0 ? '-' : '+'; |
|
2369 | - $minute = abs($second) / static::SECONDS_PER_MINUTE; |
|
2370 | - $hour = str_pad((string) floor($minute / static::MINUTES_PER_HOUR), 2, '0', STR_PAD_LEFT); |
|
2371 | - $minute = str_pad((string) (((int) $minute) % static::MINUTES_PER_HOUR), 2, '0', STR_PAD_LEFT); |
|
2372 | - |
|
2373 | - return "$symbol$hour$separator$minute"; |
|
2374 | - } |
|
2375 | - |
|
2376 | - protected static function executeStaticCallable($macro, ...$parameters) |
|
2377 | - { |
|
2378 | - return static::bindMacroContext(null, function () use (&$macro, &$parameters) { |
|
2379 | - if ($macro instanceof Closure) { |
|
2380 | - $boundMacro = @Closure::bind($macro, null, static::class); |
|
2381 | - |
|
2382 | - return ($boundMacro ?: $macro)(...$parameters); |
|
2383 | - } |
|
2384 | - |
|
2385 | - return $macro(...$parameters); |
|
2386 | - }); |
|
2387 | - } |
|
2388 | - |
|
2389 | - /** |
|
2390 | - * Dynamically handle calls to the class. |
|
2391 | - * |
|
2392 | - * @param string $method magic method name called |
|
2393 | - * @param array $parameters parameters list |
|
2394 | - * |
|
2395 | - * @throws BadMethodCallException |
|
2396 | - * |
|
2397 | - * @return mixed |
|
2398 | - */ |
|
2399 | - public static function __callStatic($method, $parameters) |
|
2400 | - { |
|
2401 | - if (!static::hasMacro($method)) { |
|
2402 | - foreach (static::getGenericMacros() as $callback) { |
|
2403 | - try { |
|
2404 | - return static::executeStaticCallable($callback, $method, ...$parameters); |
|
2405 | - } catch (BadMethodCallException $exception) { |
|
2406 | - continue; |
|
2407 | - } |
|
2408 | - } |
|
2409 | - if (static::isStrictModeEnabled()) { |
|
2410 | - throw new UnknownMethodException(sprintf('%s::%s', static::class, $method)); |
|
2411 | - } |
|
2412 | - |
|
2413 | - return null; |
|
2414 | - } |
|
2415 | - |
|
2416 | - return static::executeStaticCallable(static::$globalMacros[$method], ...$parameters); |
|
2417 | - } |
|
2418 | - |
|
2419 | - /** |
|
2420 | - * Set specified unit to new given value. |
|
2421 | - * |
|
2422 | - * @param string $unit year, month, day, hour, minute, second or microsecond |
|
2423 | - * @param int $value new value for given unit |
|
2424 | - * |
|
2425 | - * @return static |
|
2426 | - */ |
|
2427 | - public function setUnit($unit, $value = null) |
|
2428 | - { |
|
2429 | - $unit = static::singularUnit($unit); |
|
2430 | - $dateUnits = ['year', 'month', 'day']; |
|
2431 | - if (\in_array($unit, $dateUnits)) { |
|
2432 | - return $this->setDate(...array_map(function ($name) use ($unit, $value) { |
|
2433 | - return (int) ($name === $unit ? $value : $this->$name); |
|
2434 | - }, $dateUnits)); |
|
2435 | - } |
|
2436 | - |
|
2437 | - $units = ['hour', 'minute', 'second', 'micro']; |
|
2438 | - if ($unit === 'millisecond' || $unit === 'milli') { |
|
2439 | - $value *= 1000; |
|
2440 | - $unit = 'micro'; |
|
2441 | - } elseif ($unit === 'microsecond') { |
|
2442 | - $unit = 'micro'; |
|
2443 | - } |
|
2444 | - |
|
2445 | - return $this->setTime(...array_map(function ($name) use ($unit, $value) { |
|
2446 | - return (int) ($name === $unit ? $value : $this->$name); |
|
2447 | - }, $units)); |
|
2448 | - } |
|
2449 | - |
|
2450 | - /** |
|
2451 | - * Returns standardized singular of a given singular/plural unit name (in English). |
|
2452 | - * |
|
2453 | - * @param string $unit |
|
2454 | - * |
|
2455 | - * @return string |
|
2456 | - */ |
|
2457 | - public static function singularUnit(string $unit): string |
|
2458 | - { |
|
2459 | - $unit = rtrim(mb_strtolower($unit), 's'); |
|
2460 | - |
|
2461 | - if ($unit === 'centurie') { |
|
2462 | - return 'century'; |
|
2463 | - } |
|
2464 | - |
|
2465 | - if ($unit === 'millennia') { |
|
2466 | - return 'millennium'; |
|
2467 | - } |
|
2468 | - |
|
2469 | - return $unit; |
|
2470 | - } |
|
2471 | - |
|
2472 | - /** |
|
2473 | - * Returns standardized plural of a given singular/plural unit name (in English). |
|
2474 | - * |
|
2475 | - * @param string $unit |
|
2476 | - * |
|
2477 | - * @return string |
|
2478 | - */ |
|
2479 | - public static function pluralUnit(string $unit): string |
|
2480 | - { |
|
2481 | - $unit = rtrim(strtolower($unit), 's'); |
|
2482 | - |
|
2483 | - if ($unit === 'century') { |
|
2484 | - return 'centuries'; |
|
2485 | - } |
|
2486 | - |
|
2487 | - if ($unit === 'millennium' || $unit === 'millennia') { |
|
2488 | - return 'millennia'; |
|
2489 | - } |
|
2490 | - |
|
2491 | - return "{$unit}s"; |
|
2492 | - } |
|
2493 | - |
|
2494 | - protected function executeCallable($macro, ...$parameters) |
|
2495 | - { |
|
2496 | - if ($macro instanceof Closure) { |
|
2497 | - $boundMacro = @$macro->bindTo($this, static::class) ?: @$macro->bindTo(null, static::class); |
|
2498 | - |
|
2499 | - return ($boundMacro ?: $macro)(...$parameters); |
|
2500 | - } |
|
2501 | - |
|
2502 | - return $macro(...$parameters); |
|
2503 | - } |
|
2504 | - |
|
2505 | - protected function executeCallableWithContext($macro, ...$parameters) |
|
2506 | - { |
|
2507 | - return static::bindMacroContext($this, function () use (&$macro, &$parameters) { |
|
2508 | - return $this->executeCallable($macro, ...$parameters); |
|
2509 | - }); |
|
2510 | - } |
|
2511 | - |
|
2512 | - protected static function getGenericMacros() |
|
2513 | - { |
|
2514 | - foreach (static::$globalGenericMacros as $list) { |
|
2515 | - foreach ($list as $macro) { |
|
2516 | - yield $macro; |
|
2517 | - } |
|
2518 | - } |
|
2519 | - } |
|
2520 | - |
|
2521 | - /** |
|
2522 | - * Dynamically handle calls to the class. |
|
2523 | - * |
|
2524 | - * @param string $method magic method name called |
|
2525 | - * @param array $parameters parameters list |
|
2526 | - * |
|
2527 | - * @throws UnknownMethodException|BadMethodCallException|ReflectionException|Throwable |
|
2528 | - * |
|
2529 | - * @return mixed |
|
2530 | - */ |
|
2531 | - public function __call($method, $parameters) |
|
2532 | - { |
|
2533 | - $diffSizes = [ |
|
2534 | - // @mode diffForHumans |
|
2535 | - 'short' => true, |
|
2536 | - // @mode diffForHumans |
|
2537 | - 'long' => false, |
|
2538 | - ]; |
|
2539 | - $diffSyntaxModes = [ |
|
2540 | - // @call diffForHumans |
|
2541 | - 'Absolute' => CarbonInterface::DIFF_ABSOLUTE, |
|
2542 | - // @call diffForHumans |
|
2543 | - 'Relative' => CarbonInterface::DIFF_RELATIVE_AUTO, |
|
2544 | - // @call diffForHumans |
|
2545 | - 'RelativeToNow' => CarbonInterface::DIFF_RELATIVE_TO_NOW, |
|
2546 | - // @call diffForHumans |
|
2547 | - 'RelativeToOther' => CarbonInterface::DIFF_RELATIVE_TO_OTHER, |
|
2548 | - ]; |
|
2549 | - $sizePattern = implode('|', array_keys($diffSizes)); |
|
2550 | - $syntaxPattern = implode('|', array_keys($diffSyntaxModes)); |
|
2551 | - |
|
2552 | - if (preg_match("/^(?<size>$sizePattern)(?<syntax>$syntaxPattern)DiffForHumans$/", $method, $match)) { |
|
2553 | - $dates = array_filter($parameters, function ($parameter) { |
|
2554 | - return $parameter instanceof DateTimeInterface; |
|
2555 | - }); |
|
2556 | - $other = null; |
|
2557 | - |
|
2558 | - if (\count($dates)) { |
|
2559 | - $key = key($dates); |
|
2560 | - $other = current($dates); |
|
2561 | - array_splice($parameters, $key, 1); |
|
2562 | - } |
|
2563 | - |
|
2564 | - return $this->diffForHumans($other, $diffSyntaxModes[$match['syntax']], $diffSizes[$match['size']], ...$parameters); |
|
2565 | - } |
|
2566 | - |
|
2567 | - $roundedValue = $this->callRoundMethod($method, $parameters); |
|
2568 | - |
|
2569 | - if ($roundedValue !== null) { |
|
2570 | - return $roundedValue; |
|
2571 | - } |
|
2572 | - |
|
2573 | - $unit = rtrim($method, 's'); |
|
2574 | - |
|
2575 | - if (str_starts_with($unit, 'is')) { |
|
2576 | - $word = substr($unit, 2); |
|
2577 | - |
|
2578 | - if (\in_array($word, static::$days, true)) { |
|
2579 | - return $this->isDayOfWeek($word); |
|
2580 | - } |
|
2581 | - |
|
2582 | - switch ($word) { |
|
2583 | - // @call is Check if the current instance has UTC timezone. (Both isUtc and isUTC cases are valid.) |
|
2584 | - case 'Utc': |
|
2585 | - case 'UTC': |
|
2586 | - return $this->utc; |
|
2587 | - // @call is Check if the current instance has non-UTC timezone. |
|
2588 | - case 'Local': |
|
2589 | - return $this->local; |
|
2590 | - // @call is Check if the current instance is a valid date. |
|
2591 | - case 'Valid': |
|
2592 | - return $this->year !== 0; |
|
2593 | - // @call is Check if the current instance is in a daylight saving time. |
|
2594 | - case 'DST': |
|
2595 | - return $this->dst; |
|
2596 | - } |
|
2597 | - } |
|
2598 | - |
|
2599 | - $action = substr($unit, 0, 3); |
|
2600 | - $overflow = null; |
|
2601 | - |
|
2602 | - if ($action === 'set') { |
|
2603 | - $unit = strtolower(substr($unit, 3)); |
|
2604 | - } |
|
2605 | - |
|
2606 | - if (\in_array($unit, static::$units, true)) { |
|
2607 | - return $this->setUnit($unit, ...$parameters); |
|
2608 | - } |
|
2609 | - |
|
2610 | - if ($action === 'add' || $action === 'sub') { |
|
2611 | - $unit = substr($unit, 3); |
|
2612 | - |
|
2613 | - if (str_starts_with($unit, 'Real')) { |
|
2614 | - $unit = static::singularUnit(substr($unit, 4)); |
|
2615 | - |
|
2616 | - return $this->{"{$action}RealUnit"}($unit, ...$parameters); |
|
2617 | - } |
|
2618 | - |
|
2619 | - if (preg_match('/^(Month|Quarter|Year|Decade|Century|Centurie|Millennium|Millennia)s?(No|With|Without|WithNo)Overflow$/', $unit, $match)) { |
|
2620 | - $unit = $match[1]; |
|
2621 | - $overflow = $match[2] === 'With'; |
|
2622 | - } |
|
2623 | - |
|
2624 | - $unit = static::singularUnit($unit); |
|
2625 | - } |
|
2626 | - |
|
2627 | - if (static::isModifiableUnit($unit)) { |
|
2628 | - return $this->{"{$action}Unit"}($unit, $parameters[0] ?? 1, $overflow); |
|
2629 | - } |
|
2630 | - |
|
2631 | - $sixFirstLetters = substr($unit, 0, 6); |
|
2632 | - $factor = -1; |
|
2633 | - |
|
2634 | - if ($sixFirstLetters === 'isLast') { |
|
2635 | - $sixFirstLetters = 'isNext'; |
|
2636 | - $factor = 1; |
|
2637 | - } |
|
2638 | - |
|
2639 | - if ($sixFirstLetters === 'isNext') { |
|
2640 | - $lowerUnit = strtolower(substr($unit, 6)); |
|
2641 | - |
|
2642 | - if (static::isModifiableUnit($lowerUnit)) { |
|
2643 | - return $this->copy()->addUnit($lowerUnit, $factor, false)->isSameUnit($lowerUnit, ...$parameters); |
|
2644 | - } |
|
2645 | - } |
|
2646 | - |
|
2647 | - if ($sixFirstLetters === 'isSame') { |
|
2648 | - try { |
|
2649 | - return $this->isSameUnit(strtolower(substr($unit, 6)), ...$parameters); |
|
2650 | - } catch (BadComparisonUnitException $exception) { |
|
2651 | - // Try next |
|
2652 | - } |
|
2653 | - } |
|
2654 | - |
|
2655 | - if (str_starts_with($unit, 'isCurrent')) { |
|
2656 | - try { |
|
2657 | - return $this->isCurrentUnit(strtolower(substr($unit, 9))); |
|
2658 | - } catch (BadComparisonUnitException | BadMethodCallException $exception) { |
|
2659 | - // Try next |
|
2660 | - } |
|
2661 | - } |
|
2662 | - |
|
2663 | - if (str_ends_with($method, 'Until')) { |
|
2664 | - try { |
|
2665 | - $unit = static::singularUnit(substr($method, 0, -5)); |
|
2666 | - |
|
2667 | - return $this->range($parameters[0] ?? $this, $parameters[1] ?? 1, $unit); |
|
2668 | - } catch (InvalidArgumentException $exception) { |
|
2669 | - // Try macros |
|
2670 | - } |
|
2671 | - } |
|
2672 | - |
|
2673 | - return static::bindMacroContext($this, function () use (&$method, &$parameters) { |
|
2674 | - $macro = $this->getLocalMacro($method); |
|
2675 | - |
|
2676 | - if (!$macro) { |
|
2677 | - foreach ([$this->localGenericMacros ?: [], static::getGenericMacros()] as $list) { |
|
2678 | - foreach ($list as $callback) { |
|
2679 | - try { |
|
2680 | - return $this->executeCallable($callback, $method, ...$parameters); |
|
2681 | - } catch (BadMethodCallException $exception) { |
|
2682 | - continue; |
|
2683 | - } |
|
2684 | - } |
|
2685 | - } |
|
2686 | - |
|
2687 | - if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) { |
|
2688 | - throw new UnknownMethodException($method); |
|
2689 | - } |
|
2690 | - |
|
2691 | - return null; |
|
2692 | - } |
|
2693 | - |
|
2694 | - return $this->executeCallable($macro, ...$parameters); |
|
2695 | - }); |
|
2696 | - } |
|
529 | + use Boundaries; |
|
530 | + use Comparison; |
|
531 | + use Converter; |
|
532 | + use Creator; |
|
533 | + use Difference; |
|
534 | + use Macro; |
|
535 | + use Modifiers; |
|
536 | + use Mutability; |
|
537 | + use ObjectInitialisation; |
|
538 | + use Options; |
|
539 | + use Rounding; |
|
540 | + use Serialization; |
|
541 | + use Test; |
|
542 | + use Timestamp; |
|
543 | + use Units; |
|
544 | + use Week; |
|
545 | + |
|
546 | + /** |
|
547 | + * Names of days of the week. |
|
548 | + * |
|
549 | + * @var array |
|
550 | + */ |
|
551 | + protected static $days = [ |
|
552 | + // @call isDayOfWeek |
|
553 | + CarbonInterface::SUNDAY => 'Sunday', |
|
554 | + // @call isDayOfWeek |
|
555 | + CarbonInterface::MONDAY => 'Monday', |
|
556 | + // @call isDayOfWeek |
|
557 | + CarbonInterface::TUESDAY => 'Tuesday', |
|
558 | + // @call isDayOfWeek |
|
559 | + CarbonInterface::WEDNESDAY => 'Wednesday', |
|
560 | + // @call isDayOfWeek |
|
561 | + CarbonInterface::THURSDAY => 'Thursday', |
|
562 | + // @call isDayOfWeek |
|
563 | + CarbonInterface::FRIDAY => 'Friday', |
|
564 | + // @call isDayOfWeek |
|
565 | + CarbonInterface::SATURDAY => 'Saturday', |
|
566 | + ]; |
|
567 | + |
|
568 | + /** |
|
569 | + * Will UTF8 encoding be used to print localized date/time ? |
|
570 | + * |
|
571 | + * @var bool |
|
572 | + */ |
|
573 | + protected static $utf8 = false; |
|
574 | + |
|
575 | + /** |
|
576 | + * List of unit and magic methods associated as doc-comments. |
|
577 | + * |
|
578 | + * @var array |
|
579 | + */ |
|
580 | + protected static $units = [ |
|
581 | + // @call setUnit |
|
582 | + // @call addUnit |
|
583 | + 'year', |
|
584 | + // @call setUnit |
|
585 | + // @call addUnit |
|
586 | + 'month', |
|
587 | + // @call setUnit |
|
588 | + // @call addUnit |
|
589 | + 'day', |
|
590 | + // @call setUnit |
|
591 | + // @call addUnit |
|
592 | + 'hour', |
|
593 | + // @call setUnit |
|
594 | + // @call addUnit |
|
595 | + 'minute', |
|
596 | + // @call setUnit |
|
597 | + // @call addUnit |
|
598 | + 'second', |
|
599 | + // @call setUnit |
|
600 | + // @call addUnit |
|
601 | + 'milli', |
|
602 | + // @call setUnit |
|
603 | + // @call addUnit |
|
604 | + 'millisecond', |
|
605 | + // @call setUnit |
|
606 | + // @call addUnit |
|
607 | + 'micro', |
|
608 | + // @call setUnit |
|
609 | + // @call addUnit |
|
610 | + 'microsecond', |
|
611 | + ]; |
|
612 | + |
|
613 | + /** |
|
614 | + * Creates a DateTimeZone from a string, DateTimeZone or integer offset. |
|
615 | + * |
|
616 | + * @param DateTimeZone|string|int|null $object original value to get CarbonTimeZone from it. |
|
617 | + * @param DateTimeZone|string|int|null $objectDump dump of the object for error messages. |
|
618 | + * |
|
619 | + * @throws InvalidTimeZoneException |
|
620 | + * |
|
621 | + * @return CarbonTimeZone|false |
|
622 | + */ |
|
623 | + protected static function safeCreateDateTimeZone($object, $objectDump = null) |
|
624 | + { |
|
625 | + return CarbonTimeZone::instance($object, $objectDump); |
|
626 | + } |
|
627 | + |
|
628 | + /** |
|
629 | + * Get the TimeZone associated with the Carbon instance (as CarbonTimeZone). |
|
630 | + * |
|
631 | + * @return CarbonTimeZone |
|
632 | + * |
|
633 | + * @link https://php.net/manual/en/datetime.gettimezone.php |
|
634 | + */ |
|
635 | + #[ReturnTypeWillChange] |
|
636 | + public function getTimezone() |
|
637 | + { |
|
638 | + return CarbonTimeZone::instance(parent::getTimezone()); |
|
639 | + } |
|
640 | + |
|
641 | + /** |
|
642 | + * List of minimum and maximums for each unit. |
|
643 | + * |
|
644 | + * @return array |
|
645 | + */ |
|
646 | + protected static function getRangesByUnit(int $daysInMonth = 31): array |
|
647 | + { |
|
648 | + return [ |
|
649 | + // @call roundUnit |
|
650 | + 'year' => [1, 9999], |
|
651 | + // @call roundUnit |
|
652 | + 'month' => [1, static::MONTHS_PER_YEAR], |
|
653 | + // @call roundUnit |
|
654 | + 'day' => [1, $daysInMonth], |
|
655 | + // @call roundUnit |
|
656 | + 'hour' => [0, static::HOURS_PER_DAY - 1], |
|
657 | + // @call roundUnit |
|
658 | + 'minute' => [0, static::MINUTES_PER_HOUR - 1], |
|
659 | + // @call roundUnit |
|
660 | + 'second' => [0, static::SECONDS_PER_MINUTE - 1], |
|
661 | + ]; |
|
662 | + } |
|
663 | + |
|
664 | + /** |
|
665 | + * Get a copy of the instance. |
|
666 | + * |
|
667 | + * @return static |
|
668 | + */ |
|
669 | + public function copy() |
|
670 | + { |
|
671 | + return clone $this; |
|
672 | + } |
|
673 | + |
|
674 | + /** |
|
675 | + * @alias copy |
|
676 | + * |
|
677 | + * Get a copy of the instance. |
|
678 | + * |
|
679 | + * @return static |
|
680 | + */ |
|
681 | + public function clone() |
|
682 | + { |
|
683 | + return clone $this; |
|
684 | + } |
|
685 | + |
|
686 | + /** |
|
687 | + * Clone the current instance if it's mutable. |
|
688 | + * |
|
689 | + * This method is convenient to ensure you don't mutate the initial object |
|
690 | + * but avoid to make a useless copy of it if it's already immutable. |
|
691 | + * |
|
692 | + * @return static |
|
693 | + */ |
|
694 | + public function avoidMutation(): self |
|
695 | + { |
|
696 | + if ($this instanceof DateTimeImmutable) { |
|
697 | + return $this; |
|
698 | + } |
|
699 | + |
|
700 | + return clone $this; |
|
701 | + } |
|
702 | + |
|
703 | + /** |
|
704 | + * Returns a present instance in the same timezone. |
|
705 | + * |
|
706 | + * @return static |
|
707 | + */ |
|
708 | + public function nowWithSameTz() |
|
709 | + { |
|
710 | + return static::now($this->getTimezone()); |
|
711 | + } |
|
712 | + |
|
713 | + /** |
|
714 | + * Throws an exception if the given object is not a DateTime and does not implement DateTimeInterface. |
|
715 | + * |
|
716 | + * @param mixed $date |
|
717 | + * @param string|array $other |
|
718 | + * |
|
719 | + * @throws InvalidTypeException |
|
720 | + */ |
|
721 | + protected static function expectDateTime($date, $other = []) |
|
722 | + { |
|
723 | + $message = 'Expected '; |
|
724 | + foreach ((array) $other as $expect) { |
|
725 | + $message .= "$expect, "; |
|
726 | + } |
|
727 | + |
|
728 | + if (!$date instanceof DateTime && !$date instanceof DateTimeInterface) { |
|
729 | + throw new InvalidTypeException( |
|
730 | + $message.'DateTime or DateTimeInterface, '. |
|
731 | + (\is_object($date) ? \get_class($date) : \gettype($date)).' given' |
|
732 | + ); |
|
733 | + } |
|
734 | + } |
|
735 | + |
|
736 | + /** |
|
737 | + * Return the Carbon instance passed through, a now instance in the same timezone |
|
738 | + * if null given or parse the input if string given. |
|
739 | + * |
|
740 | + * @param Carbon|DateTimeInterface|string|null $date |
|
741 | + * |
|
742 | + * @return static |
|
743 | + */ |
|
744 | + protected function resolveCarbon($date = null) |
|
745 | + { |
|
746 | + if (!$date) { |
|
747 | + return $this->nowWithSameTz(); |
|
748 | + } |
|
749 | + |
|
750 | + if (\is_string($date)) { |
|
751 | + return static::parse($date, $this->getTimezone()); |
|
752 | + } |
|
753 | + |
|
754 | + static::expectDateTime($date, ['null', 'string']); |
|
755 | + |
|
756 | + return $date instanceof self ? $date : static::instance($date); |
|
757 | + } |
|
758 | + |
|
759 | + /** |
|
760 | + * Return the Carbon instance passed through, a now instance in UTC |
|
761 | + * if null given or parse the input if string given (using current timezone |
|
762 | + * then switching to UTC). |
|
763 | + * |
|
764 | + * @param Carbon|DateTimeInterface|string|null $date |
|
765 | + * |
|
766 | + * @return static |
|
767 | + */ |
|
768 | + protected function resolveUTC($date = null): self |
|
769 | + { |
|
770 | + if (!$date) { |
|
771 | + return static::now('UTC'); |
|
772 | + } |
|
773 | + |
|
774 | + if (\is_string($date)) { |
|
775 | + return static::parse($date, $this->getTimezone())->utc(); |
|
776 | + } |
|
777 | + |
|
778 | + static::expectDateTime($date, ['null', 'string']); |
|
779 | + |
|
780 | + return $date instanceof self ? $date : static::instance($date)->utc(); |
|
781 | + } |
|
782 | + |
|
783 | + /** |
|
784 | + * Return the Carbon instance passed through, a now instance in the same timezone |
|
785 | + * if null given or parse the input if string given. |
|
786 | + * |
|
787 | + * @param Carbon|\Carbon\CarbonPeriod|\Carbon\CarbonInterval|\DateInterval|\DatePeriod|DateTimeInterface|string|null $date |
|
788 | + * |
|
789 | + * @return static |
|
790 | + */ |
|
791 | + public function carbonize($date = null) |
|
792 | + { |
|
793 | + if ($date instanceof DateInterval) { |
|
794 | + return $this->avoidMutation()->add($date); |
|
795 | + } |
|
796 | + |
|
797 | + if ($date instanceof DatePeriod || $date instanceof CarbonPeriod) { |
|
798 | + $date = $date->getStartDate(); |
|
799 | + } |
|
800 | + |
|
801 | + return $this->resolveCarbon($date); |
|
802 | + } |
|
803 | + |
|
804 | + /////////////////////////////////////////////////////////////////// |
|
805 | + ///////////////////////// GETTERS AND SETTERS ///////////////////// |
|
806 | + /////////////////////////////////////////////////////////////////// |
|
807 | + |
|
808 | + /** |
|
809 | + * Get a part of the Carbon object |
|
810 | + * |
|
811 | + * @param string $name |
|
812 | + * |
|
813 | + * @throws UnknownGetterException |
|
814 | + * |
|
815 | + * @return string|int|bool|DateTimeZone|null |
|
816 | + */ |
|
817 | + public function __get($name) |
|
818 | + { |
|
819 | + return $this->get($name); |
|
820 | + } |
|
821 | + |
|
822 | + /** |
|
823 | + * Get a part of the Carbon object |
|
824 | + * |
|
825 | + * @param string $name |
|
826 | + * |
|
827 | + * @throws UnknownGetterException |
|
828 | + * |
|
829 | + * @return string|int|bool|DateTimeZone|null |
|
830 | + */ |
|
831 | + public function get($name) |
|
832 | + { |
|
833 | + static $formats = [ |
|
834 | + // @property int |
|
835 | + 'year' => 'Y', |
|
836 | + // @property int |
|
837 | + 'yearIso' => 'o', |
|
838 | + // @property int |
|
839 | + // @call isSameUnit |
|
840 | + 'month' => 'n', |
|
841 | + // @property int |
|
842 | + 'day' => 'j', |
|
843 | + // @property int |
|
844 | + 'hour' => 'G', |
|
845 | + // @property int |
|
846 | + 'minute' => 'i', |
|
847 | + // @property int |
|
848 | + 'second' => 's', |
|
849 | + // @property int |
|
850 | + 'micro' => 'u', |
|
851 | + // @property int |
|
852 | + 'microsecond' => 'u', |
|
853 | + // @property-read int 0 (for Sunday) through 6 (for Saturday) |
|
854 | + 'dayOfWeek' => 'w', |
|
855 | + // @property-read int 1 (for Monday) through 7 (for Sunday) |
|
856 | + 'dayOfWeekIso' => 'N', |
|
857 | + // @property-read int ISO-8601 week number of year, weeks starting on Monday |
|
858 | + 'weekOfYear' => 'W', |
|
859 | + // @property-read int number of days in the given month |
|
860 | + 'daysInMonth' => 't', |
|
861 | + // @property int|float|string seconds since the Unix Epoch |
|
862 | + 'timestamp' => 'U', |
|
863 | + // @property-read string "am"/"pm" (Ante meridiem or Post meridiem latin lowercase mark) |
|
864 | + 'latinMeridiem' => 'a', |
|
865 | + // @property-read string "AM"/"PM" (Ante meridiem or Post meridiem latin uppercase mark) |
|
866 | + 'latinUpperMeridiem' => 'A', |
|
867 | + // @property string the day of week in English |
|
868 | + 'englishDayOfWeek' => 'l', |
|
869 | + // @property string the abbreviated day of week in English |
|
870 | + 'shortEnglishDayOfWeek' => 'D', |
|
871 | + // @property string the month in English |
|
872 | + 'englishMonth' => 'F', |
|
873 | + // @property string the abbreviated month in English |
|
874 | + 'shortEnglishMonth' => 'M', |
|
875 | + // @property string the day of week in current locale LC_TIME |
|
876 | + // @deprecated |
|
877 | + // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
878 | + // replacement: Use ->isoFormat('MMM') instead. |
|
879 | + // since: 2.55.0 |
|
880 | + 'localeDayOfWeek' => '%A', |
|
881 | + // @property string the abbreviated day of week in current locale LC_TIME |
|
882 | + // @deprecated |
|
883 | + // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
884 | + // replacement: Use ->isoFormat('dddd') instead. |
|
885 | + // since: 2.55.0 |
|
886 | + 'shortLocaleDayOfWeek' => '%a', |
|
887 | + // @property string the month in current locale LC_TIME |
|
888 | + // @deprecated |
|
889 | + // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
890 | + // replacement: Use ->isoFormat('ddd') instead. |
|
891 | + // since: 2.55.0 |
|
892 | + 'localeMonth' => '%B', |
|
893 | + // @property string the abbreviated month in current locale LC_TIME |
|
894 | + // @deprecated |
|
895 | + // reason: It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
896 | + // replacement: Use ->isoFormat('MMMM') instead. |
|
897 | + // since: 2.55.0 |
|
898 | + 'shortLocaleMonth' => '%b', |
|
899 | + // @property-read string $timezoneAbbreviatedName the current timezone abbreviated name |
|
900 | + 'timezoneAbbreviatedName' => 'T', |
|
901 | + // @property-read string $tzAbbrName alias of $timezoneAbbreviatedName |
|
902 | + 'tzAbbrName' => 'T', |
|
903 | + ]; |
|
904 | + |
|
905 | + switch (true) { |
|
906 | + case isset($formats[$name]): |
|
907 | + $format = $formats[$name]; |
|
908 | + $method = str_starts_with($format, '%') ? 'formatLocalized' : 'rawFormat'; |
|
909 | + $value = $this->$method($format); |
|
910 | + |
|
911 | + return is_numeric($value) ? (int) $value : $value; |
|
912 | + |
|
913 | + // @property-read string long name of weekday translated according to Carbon locale, in english if no translation available for current language |
|
914 | + case $name === 'dayName': |
|
915 | + return $this->getTranslatedDayName(); |
|
916 | + // @property-read string short name of weekday translated according to Carbon locale, in english if no translation available for current language |
|
917 | + case $name === 'shortDayName': |
|
918 | + return $this->getTranslatedShortDayName(); |
|
919 | + // @property-read string very short name of weekday translated according to Carbon locale, in english if no translation available for current language |
|
920 | + case $name === 'minDayName': |
|
921 | + return $this->getTranslatedMinDayName(); |
|
922 | + // @property-read string long name of month translated according to Carbon locale, in english if no translation available for current language |
|
923 | + case $name === 'monthName': |
|
924 | + return $this->getTranslatedMonthName(); |
|
925 | + // @property-read string short name of month translated according to Carbon locale, in english if no translation available for current language |
|
926 | + case $name === 'shortMonthName': |
|
927 | + return $this->getTranslatedShortMonthName(); |
|
928 | + // @property-read string lowercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language |
|
929 | + case $name === 'meridiem': |
|
930 | + return $this->meridiem(true); |
|
931 | + // @property-read string uppercase meridiem mark translated according to Carbon locale, in latin if no translation available for current language |
|
932 | + case $name === 'upperMeridiem': |
|
933 | + return $this->meridiem(); |
|
934 | + // @property-read int current hour from 1 to 24 |
|
935 | + case $name === 'noZeroHour': |
|
936 | + return $this->hour ?: 24; |
|
937 | + // @property int |
|
938 | + case $name === 'milliseconds': |
|
939 | + // @property int |
|
940 | + case $name === 'millisecond': |
|
941 | + // @property int |
|
942 | + case $name === 'milli': |
|
943 | + return (int) floor(((int) $this->rawFormat('u')) / 1000); |
|
944 | + |
|
945 | + // @property int 1 through 53 |
|
946 | + case $name === 'week': |
|
947 | + return (int) $this->week(); |
|
948 | + |
|
949 | + // @property int 1 through 53 |
|
950 | + case $name === 'isoWeek': |
|
951 | + return (int) $this->isoWeek(); |
|
952 | + |
|
953 | + // @property int year according to week format |
|
954 | + case $name === 'weekYear': |
|
955 | + return (int) $this->weekYear(); |
|
956 | + |
|
957 | + // @property int year according to ISO week format |
|
958 | + case $name === 'isoWeekYear': |
|
959 | + return (int) $this->isoWeekYear(); |
|
960 | + |
|
961 | + // @property-read int 51 through 53 |
|
962 | + case $name === 'weeksInYear': |
|
963 | + return $this->weeksInYear(); |
|
964 | + |
|
965 | + // @property-read int 51 through 53 |
|
966 | + case $name === 'isoWeeksInYear': |
|
967 | + return $this->isoWeeksInYear(); |
|
968 | + |
|
969 | + // @property-read int 1 through 5 |
|
970 | + case $name === 'weekOfMonth': |
|
971 | + return (int) ceil($this->day / static::DAYS_PER_WEEK); |
|
972 | + |
|
973 | + // @property-read int 1 through 5 |
|
974 | + case $name === 'weekNumberInMonth': |
|
975 | + return (int) ceil(($this->day + $this->avoidMutation()->startOfMonth()->dayOfWeekIso - 1) / static::DAYS_PER_WEEK); |
|
976 | + |
|
977 | + // @property-read int 0 through 6 |
|
978 | + case $name === 'firstWeekDay': |
|
979 | + return $this->localTranslator ? ($this->getTranslationMessage('first_day_of_week') ?? 0) : static::getWeekStartsAt(); |
|
980 | + |
|
981 | + // @property-read int 0 through 6 |
|
982 | + case $name === 'lastWeekDay': |
|
983 | + return $this->localTranslator ? (($this->getTranslationMessage('first_day_of_week') ?? 0) + static::DAYS_PER_WEEK - 1) % static::DAYS_PER_WEEK : static::getWeekEndsAt(); |
|
984 | + |
|
985 | + // @property int 1 through 366 |
|
986 | + case $name === 'dayOfYear': |
|
987 | + return 1 + (int) ($this->rawFormat('z')); |
|
988 | + |
|
989 | + // @property-read int 365 or 366 |
|
990 | + case $name === 'daysInYear': |
|
991 | + return $this->isLeapYear() ? 366 : 365; |
|
992 | + |
|
993 | + // @property int does a diffInYears() with default parameters |
|
994 | + case $name === 'age': |
|
995 | + return $this->diffInYears(); |
|
996 | + |
|
997 | + // @property-read int the quarter of this instance, 1 - 4 |
|
998 | + // @call isSameUnit |
|
999 | + case $name === 'quarter': |
|
1000 | + return (int) ceil($this->month / static::MONTHS_PER_QUARTER); |
|
1001 | + |
|
1002 | + // @property-read int the decade of this instance |
|
1003 | + // @call isSameUnit |
|
1004 | + case $name === 'decade': |
|
1005 | + return (int) ceil($this->year / static::YEARS_PER_DECADE); |
|
1006 | + |
|
1007 | + // @property-read int the century of this instance |
|
1008 | + // @call isSameUnit |
|
1009 | + case $name === 'century': |
|
1010 | + $factor = 1; |
|
1011 | + $year = $this->year; |
|
1012 | + if ($year < 0) { |
|
1013 | + $year = -$year; |
|
1014 | + $factor = -1; |
|
1015 | + } |
|
1016 | + |
|
1017 | + return (int) ($factor * ceil($year / static::YEARS_PER_CENTURY)); |
|
1018 | + |
|
1019 | + // @property-read int the millennium of this instance |
|
1020 | + // @call isSameUnit |
|
1021 | + case $name === 'millennium': |
|
1022 | + $factor = 1; |
|
1023 | + $year = $this->year; |
|
1024 | + if ($year < 0) { |
|
1025 | + $year = -$year; |
|
1026 | + $factor = -1; |
|
1027 | + } |
|
1028 | + |
|
1029 | + return (int) ($factor * ceil($year / static::YEARS_PER_MILLENNIUM)); |
|
1030 | + |
|
1031 | + // @property int the timezone offset in seconds from UTC |
|
1032 | + case $name === 'offset': |
|
1033 | + return $this->getOffset(); |
|
1034 | + |
|
1035 | + // @property int the timezone offset in minutes from UTC |
|
1036 | + case $name === 'offsetMinutes': |
|
1037 | + return $this->getOffset() / static::SECONDS_PER_MINUTE; |
|
1038 | + |
|
1039 | + // @property int the timezone offset in hours from UTC |
|
1040 | + case $name === 'offsetHours': |
|
1041 | + return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR; |
|
1042 | + |
|
1043 | + // @property-read bool daylight savings time indicator, true if DST, false otherwise |
|
1044 | + case $name === 'dst': |
|
1045 | + return $this->rawFormat('I') === '1'; |
|
1046 | + |
|
1047 | + // @property-read bool checks if the timezone is local, true if local, false otherwise |
|
1048 | + case $name === 'local': |
|
1049 | + return $this->getOffset() === $this->avoidMutation()->setTimezone(date_default_timezone_get())->getOffset(); |
|
1050 | + |
|
1051 | + // @property-read bool checks if the timezone is UTC, true if UTC, false otherwise |
|
1052 | + case $name === 'utc': |
|
1053 | + return $this->getOffset() === 0; |
|
1054 | + |
|
1055 | + // @property CarbonTimeZone $timezone the current timezone |
|
1056 | + // @property CarbonTimeZone $tz alias of $timezone |
|
1057 | + case $name === 'timezone' || $name === 'tz': |
|
1058 | + return CarbonTimeZone::instance($this->getTimezone()); |
|
1059 | + |
|
1060 | + // @property-read string $timezoneName the current timezone name |
|
1061 | + // @property-read string $tzName alias of $timezoneName |
|
1062 | + case $name === 'timezoneName' || $name === 'tzName': |
|
1063 | + return $this->getTimezone()->getName(); |
|
1064 | + |
|
1065 | + // @property-read string locale of the current instance |
|
1066 | + case $name === 'locale': |
|
1067 | + return $this->getTranslatorLocale(); |
|
1068 | + |
|
1069 | + default: |
|
1070 | + $macro = $this->getLocalMacro('get'.ucfirst($name)); |
|
1071 | + |
|
1072 | + if ($macro) { |
|
1073 | + return $this->executeCallableWithContext($macro); |
|
1074 | + } |
|
1075 | + |
|
1076 | + throw new UnknownGetterException($name); |
|
1077 | + } |
|
1078 | + } |
|
1079 | + |
|
1080 | + /** |
|
1081 | + * Check if an attribute exists on the object |
|
1082 | + * |
|
1083 | + * @param string $name |
|
1084 | + * |
|
1085 | + * @return bool |
|
1086 | + */ |
|
1087 | + public function __isset($name) |
|
1088 | + { |
|
1089 | + try { |
|
1090 | + $this->__get($name); |
|
1091 | + } catch (UnknownGetterException | ReflectionException $e) { |
|
1092 | + return false; |
|
1093 | + } |
|
1094 | + |
|
1095 | + return true; |
|
1096 | + } |
|
1097 | + |
|
1098 | + /** |
|
1099 | + * Set a part of the Carbon object |
|
1100 | + * |
|
1101 | + * @param string $name |
|
1102 | + * @param string|int|DateTimeZone $value |
|
1103 | + * |
|
1104 | + * @throws UnknownSetterException|ReflectionException |
|
1105 | + * |
|
1106 | + * @return void |
|
1107 | + */ |
|
1108 | + public function __set($name, $value) |
|
1109 | + { |
|
1110 | + if ($this->constructedObjectId === spl_object_hash($this)) { |
|
1111 | + $this->set($name, $value); |
|
1112 | + |
|
1113 | + return; |
|
1114 | + } |
|
1115 | + |
|
1116 | + $this->$name = $value; |
|
1117 | + } |
|
1118 | + |
|
1119 | + /** |
|
1120 | + * Set a part of the Carbon object |
|
1121 | + * |
|
1122 | + * @param string|array $name |
|
1123 | + * @param string|int|DateTimeZone $value |
|
1124 | + * |
|
1125 | + * @throws ImmutableException|UnknownSetterException |
|
1126 | + * |
|
1127 | + * @return $this |
|
1128 | + */ |
|
1129 | + public function set($name, $value = null) |
|
1130 | + { |
|
1131 | + if ($this->isImmutable()) { |
|
1132 | + throw new ImmutableException(sprintf('%s class', static::class)); |
|
1133 | + } |
|
1134 | + |
|
1135 | + if (\is_array($name)) { |
|
1136 | + foreach ($name as $key => $value) { |
|
1137 | + $this->set($key, $value); |
|
1138 | + } |
|
1139 | + |
|
1140 | + return $this; |
|
1141 | + } |
|
1142 | + |
|
1143 | + switch ($name) { |
|
1144 | + case 'milliseconds': |
|
1145 | + case 'millisecond': |
|
1146 | + case 'milli': |
|
1147 | + case 'microseconds': |
|
1148 | + case 'microsecond': |
|
1149 | + case 'micro': |
|
1150 | + if (str_starts_with($name, 'milli')) { |
|
1151 | + $value *= 1000; |
|
1152 | + } |
|
1153 | + |
|
1154 | + while ($value < 0) { |
|
1155 | + $this->subSecond(); |
|
1156 | + $value += static::MICROSECONDS_PER_SECOND; |
|
1157 | + } |
|
1158 | + |
|
1159 | + while ($value >= static::MICROSECONDS_PER_SECOND) { |
|
1160 | + $this->addSecond(); |
|
1161 | + $value -= static::MICROSECONDS_PER_SECOND; |
|
1162 | + } |
|
1163 | + |
|
1164 | + $this->modify($this->rawFormat('H:i:s.').str_pad((string) round($value), 6, '0', STR_PAD_LEFT)); |
|
1165 | + |
|
1166 | + break; |
|
1167 | + |
|
1168 | + case 'year': |
|
1169 | + case 'month': |
|
1170 | + case 'day': |
|
1171 | + case 'hour': |
|
1172 | + case 'minute': |
|
1173 | + case 'second': |
|
1174 | + [$year, $month, $day, $hour, $minute, $second] = array_map('intval', explode('-', $this->rawFormat('Y-n-j-G-i-s'))); |
|
1175 | + $$name = $value; |
|
1176 | + $this->setDateTime($year, $month, $day, $hour, $minute, $second); |
|
1177 | + |
|
1178 | + break; |
|
1179 | + |
|
1180 | + case 'week': |
|
1181 | + $this->week($value); |
|
1182 | + |
|
1183 | + break; |
|
1184 | + |
|
1185 | + case 'isoWeek': |
|
1186 | + $this->isoWeek($value); |
|
1187 | + |
|
1188 | + break; |
|
1189 | + |
|
1190 | + case 'weekYear': |
|
1191 | + $this->weekYear($value); |
|
1192 | + |
|
1193 | + break; |
|
1194 | + |
|
1195 | + case 'isoWeekYear': |
|
1196 | + $this->isoWeekYear($value); |
|
1197 | + |
|
1198 | + break; |
|
1199 | + |
|
1200 | + case 'dayOfYear': |
|
1201 | + $this->addDays($value - $this->dayOfYear); |
|
1202 | + |
|
1203 | + break; |
|
1204 | + |
|
1205 | + case 'timestamp': |
|
1206 | + $this->setTimestamp($value); |
|
1207 | + |
|
1208 | + break; |
|
1209 | + |
|
1210 | + case 'offset': |
|
1211 | + $this->setTimezone(static::safeCreateDateTimeZone($value / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR)); |
|
1212 | + |
|
1213 | + break; |
|
1214 | + |
|
1215 | + case 'offsetMinutes': |
|
1216 | + $this->setTimezone(static::safeCreateDateTimeZone($value / static::MINUTES_PER_HOUR)); |
|
1217 | + |
|
1218 | + break; |
|
1219 | + |
|
1220 | + case 'offsetHours': |
|
1221 | + $this->setTimezone(static::safeCreateDateTimeZone($value)); |
|
1222 | + |
|
1223 | + break; |
|
1224 | + |
|
1225 | + case 'timezone': |
|
1226 | + case 'tz': |
|
1227 | + $this->setTimezone($value); |
|
1228 | + |
|
1229 | + break; |
|
1230 | + |
|
1231 | + default: |
|
1232 | + $macro = $this->getLocalMacro('set'.ucfirst($name)); |
|
1233 | + |
|
1234 | + if ($macro) { |
|
1235 | + $this->executeCallableWithContext($macro, $value); |
|
1236 | + |
|
1237 | + break; |
|
1238 | + } |
|
1239 | + |
|
1240 | + if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) { |
|
1241 | + throw new UnknownSetterException($name); |
|
1242 | + } |
|
1243 | + |
|
1244 | + $this->$name = $value; |
|
1245 | + } |
|
1246 | + |
|
1247 | + return $this; |
|
1248 | + } |
|
1249 | + |
|
1250 | + protected function getTranslatedFormByRegExp($baseKey, $keySuffix, $context, $subKey, $defaultValue) |
|
1251 | + { |
|
1252 | + $key = $baseKey.$keySuffix; |
|
1253 | + $standaloneKey = "{$key}_standalone"; |
|
1254 | + $baseTranslation = $this->getTranslationMessage($key); |
|
1255 | + |
|
1256 | + if ($baseTranslation instanceof Closure) { |
|
1257 | + return $baseTranslation($this, $context, $subKey) ?: $defaultValue; |
|
1258 | + } |
|
1259 | + |
|
1260 | + if ( |
|
1261 | + $this->getTranslationMessage("$standaloneKey.$subKey") && |
|
1262 | + (!$context || (($regExp = $this->getTranslationMessage("{$baseKey}_regexp")) && !preg_match($regExp, $context))) |
|
1263 | + ) { |
|
1264 | + $key = $standaloneKey; |
|
1265 | + } |
|
1266 | + |
|
1267 | + return $this->getTranslationMessage("$key.$subKey", null, $defaultValue); |
|
1268 | + } |
|
1269 | + |
|
1270 | + /** |
|
1271 | + * Get the translation of the current week day name (with context for languages with multiple forms). |
|
1272 | + * |
|
1273 | + * @param string|null $context whole format string |
|
1274 | + * @param string $keySuffix "", "_short" or "_min" |
|
1275 | + * @param string|null $defaultValue default value if translation missing |
|
1276 | + * |
|
1277 | + * @return string |
|
1278 | + */ |
|
1279 | + public function getTranslatedDayName($context = null, $keySuffix = '', $defaultValue = null) |
|
1280 | + { |
|
1281 | + return $this->getTranslatedFormByRegExp('weekdays', $keySuffix, $context, $this->dayOfWeek, $defaultValue ?: $this->englishDayOfWeek); |
|
1282 | + } |
|
1283 | + |
|
1284 | + /** |
|
1285 | + * Get the translation of the current short week day name (with context for languages with multiple forms). |
|
1286 | + * |
|
1287 | + * @param string|null $context whole format string |
|
1288 | + * |
|
1289 | + * @return string |
|
1290 | + */ |
|
1291 | + public function getTranslatedShortDayName($context = null) |
|
1292 | + { |
|
1293 | + return $this->getTranslatedDayName($context, '_short', $this->shortEnglishDayOfWeek); |
|
1294 | + } |
|
1295 | + |
|
1296 | + /** |
|
1297 | + * Get the translation of the current abbreviated week day name (with context for languages with multiple forms). |
|
1298 | + * |
|
1299 | + * @param string|null $context whole format string |
|
1300 | + * |
|
1301 | + * @return string |
|
1302 | + */ |
|
1303 | + public function getTranslatedMinDayName($context = null) |
|
1304 | + { |
|
1305 | + return $this->getTranslatedDayName($context, '_min', $this->shortEnglishDayOfWeek); |
|
1306 | + } |
|
1307 | + |
|
1308 | + /** |
|
1309 | + * Get the translation of the current month day name (with context for languages with multiple forms). |
|
1310 | + * |
|
1311 | + * @param string|null $context whole format string |
|
1312 | + * @param string $keySuffix "" or "_short" |
|
1313 | + * @param string|null $defaultValue default value if translation missing |
|
1314 | + * |
|
1315 | + * @return string |
|
1316 | + */ |
|
1317 | + public function getTranslatedMonthName($context = null, $keySuffix = '', $defaultValue = null) |
|
1318 | + { |
|
1319 | + return $this->getTranslatedFormByRegExp('months', $keySuffix, $context, $this->month - 1, $defaultValue ?: $this->englishMonth); |
|
1320 | + } |
|
1321 | + |
|
1322 | + /** |
|
1323 | + * Get the translation of the current short month day name (with context for languages with multiple forms). |
|
1324 | + * |
|
1325 | + * @param string|null $context whole format string |
|
1326 | + * |
|
1327 | + * @return string |
|
1328 | + */ |
|
1329 | + public function getTranslatedShortMonthName($context = null) |
|
1330 | + { |
|
1331 | + return $this->getTranslatedMonthName($context, '_short', $this->shortEnglishMonth); |
|
1332 | + } |
|
1333 | + |
|
1334 | + /** |
|
1335 | + * Get/set the day of year. |
|
1336 | + * |
|
1337 | + * @param int|null $value new value for day of year if using as setter. |
|
1338 | + * |
|
1339 | + * @return static|int |
|
1340 | + */ |
|
1341 | + public function dayOfYear($value = null) |
|
1342 | + { |
|
1343 | + $dayOfYear = $this->dayOfYear; |
|
1344 | + |
|
1345 | + return $value === null ? $dayOfYear : $this->addDays($value - $dayOfYear); |
|
1346 | + } |
|
1347 | + |
|
1348 | + /** |
|
1349 | + * Get/set the weekday from 0 (Sunday) to 6 (Saturday). |
|
1350 | + * |
|
1351 | + * @param int|null $value new value for weekday if using as setter. |
|
1352 | + * |
|
1353 | + * @return static|int |
|
1354 | + */ |
|
1355 | + public function weekday($value = null) |
|
1356 | + { |
|
1357 | + $dayOfWeek = ($this->dayOfWeek + 7 - (int) ($this->getTranslationMessage('first_day_of_week') ?? 0)) % 7; |
|
1358 | + |
|
1359 | + return $value === null ? $dayOfWeek : $this->addDays($value - $dayOfWeek); |
|
1360 | + } |
|
1361 | + |
|
1362 | + /** |
|
1363 | + * Get/set the ISO weekday from 1 (Monday) to 7 (Sunday). |
|
1364 | + * |
|
1365 | + * @param int|null $value new value for weekday if using as setter. |
|
1366 | + * |
|
1367 | + * @return static|int |
|
1368 | + */ |
|
1369 | + public function isoWeekday($value = null) |
|
1370 | + { |
|
1371 | + $dayOfWeekIso = $this->dayOfWeekIso; |
|
1372 | + |
|
1373 | + return $value === null ? $dayOfWeekIso : $this->addDays($value - $dayOfWeekIso); |
|
1374 | + } |
|
1375 | + |
|
1376 | + /** |
|
1377 | + * Set any unit to a new value without overflowing current other unit given. |
|
1378 | + * |
|
1379 | + * @param string $valueUnit unit name to modify |
|
1380 | + * @param int $value new value for the input unit |
|
1381 | + * @param string $overflowUnit unit name to not overflow |
|
1382 | + * |
|
1383 | + * @return static |
|
1384 | + */ |
|
1385 | + public function setUnitNoOverflow($valueUnit, $value, $overflowUnit) |
|
1386 | + { |
|
1387 | + try { |
|
1388 | + $original = $this->avoidMutation(); |
|
1389 | + /** @var static $date */ |
|
1390 | + $date = $this->$valueUnit($value); |
|
1391 | + $end = $original->avoidMutation()->endOf($overflowUnit); |
|
1392 | + $start = $original->avoidMutation()->startOf($overflowUnit); |
|
1393 | + if ($date < $start) { |
|
1394 | + $date = $date->setDateTimeFrom($start); |
|
1395 | + } elseif ($date > $end) { |
|
1396 | + $date = $date->setDateTimeFrom($end); |
|
1397 | + } |
|
1398 | + |
|
1399 | + return $date; |
|
1400 | + } catch (BadMethodCallException | ReflectionException $exception) { |
|
1401 | + throw new UnknownUnitException($valueUnit, 0, $exception); |
|
1402 | + } |
|
1403 | + } |
|
1404 | + |
|
1405 | + /** |
|
1406 | + * Add any unit to a new value without overflowing current other unit given. |
|
1407 | + * |
|
1408 | + * @param string $valueUnit unit name to modify |
|
1409 | + * @param int $value amount to add to the input unit |
|
1410 | + * @param string $overflowUnit unit name to not overflow |
|
1411 | + * |
|
1412 | + * @return static |
|
1413 | + */ |
|
1414 | + public function addUnitNoOverflow($valueUnit, $value, $overflowUnit) |
|
1415 | + { |
|
1416 | + return $this->setUnitNoOverflow($valueUnit, $this->$valueUnit + $value, $overflowUnit); |
|
1417 | + } |
|
1418 | + |
|
1419 | + /** |
|
1420 | + * Subtract any unit to a new value without overflowing current other unit given. |
|
1421 | + * |
|
1422 | + * @param string $valueUnit unit name to modify |
|
1423 | + * @param int $value amount to subtract to the input unit |
|
1424 | + * @param string $overflowUnit unit name to not overflow |
|
1425 | + * |
|
1426 | + * @return static |
|
1427 | + */ |
|
1428 | + public function subUnitNoOverflow($valueUnit, $value, $overflowUnit) |
|
1429 | + { |
|
1430 | + return $this->setUnitNoOverflow($valueUnit, $this->$valueUnit - $value, $overflowUnit); |
|
1431 | + } |
|
1432 | + |
|
1433 | + /** |
|
1434 | + * Returns the minutes offset to UTC if no arguments passed, else set the timezone with given minutes shift passed. |
|
1435 | + * |
|
1436 | + * @param int|null $minuteOffset |
|
1437 | + * |
|
1438 | + * @return int|static |
|
1439 | + */ |
|
1440 | + public function utcOffset(int $minuteOffset = null) |
|
1441 | + { |
|
1442 | + if (\func_num_args() < 1) { |
|
1443 | + return $this->offsetMinutes; |
|
1444 | + } |
|
1445 | + |
|
1446 | + return $this->setTimezone(CarbonTimeZone::createFromMinuteOffset($minuteOffset)); |
|
1447 | + } |
|
1448 | + |
|
1449 | + /** |
|
1450 | + * Set the date with gregorian year, month and day numbers. |
|
1451 | + * |
|
1452 | + * @see https://php.net/manual/en/datetime.setdate.php |
|
1453 | + * |
|
1454 | + * @param int $year |
|
1455 | + * @param int $month |
|
1456 | + * @param int $day |
|
1457 | + * |
|
1458 | + * @return static |
|
1459 | + */ |
|
1460 | + #[ReturnTypeWillChange] |
|
1461 | + public function setDate($year, $month, $day) |
|
1462 | + { |
|
1463 | + return parent::setDate((int) $year, (int) $month, (int) $day); |
|
1464 | + } |
|
1465 | + |
|
1466 | + /** |
|
1467 | + * Set a date according to the ISO 8601 standard - using weeks and day offsets rather than specific dates. |
|
1468 | + * |
|
1469 | + * @see https://php.net/manual/en/datetime.setisodate.php |
|
1470 | + * |
|
1471 | + * @param int $year |
|
1472 | + * @param int $week |
|
1473 | + * @param int $day |
|
1474 | + * |
|
1475 | + * @return static |
|
1476 | + */ |
|
1477 | + #[ReturnTypeWillChange] |
|
1478 | + public function setISODate($year, $week, $day = 1) |
|
1479 | + { |
|
1480 | + return parent::setISODate((int) $year, (int) $week, (int) $day); |
|
1481 | + } |
|
1482 | + |
|
1483 | + /** |
|
1484 | + * Set the date and time all together. |
|
1485 | + * |
|
1486 | + * @param int $year |
|
1487 | + * @param int $month |
|
1488 | + * @param int $day |
|
1489 | + * @param int $hour |
|
1490 | + * @param int $minute |
|
1491 | + * @param int $second |
|
1492 | + * @param int $microseconds |
|
1493 | + * |
|
1494 | + * @return static |
|
1495 | + */ |
|
1496 | + public function setDateTime($year, $month, $day, $hour, $minute, $second = 0, $microseconds = 0) |
|
1497 | + { |
|
1498 | + return $this->setDate($year, $month, $day)->setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds); |
|
1499 | + } |
|
1500 | + |
|
1501 | + /** |
|
1502 | + * Resets the current time of the DateTime object to a different time. |
|
1503 | + * |
|
1504 | + * @see https://php.net/manual/en/datetime.settime.php |
|
1505 | + * |
|
1506 | + * @param int $hour |
|
1507 | + * @param int $minute |
|
1508 | + * @param int $second |
|
1509 | + * @param int $microseconds |
|
1510 | + * |
|
1511 | + * @return static |
|
1512 | + */ |
|
1513 | + #[ReturnTypeWillChange] |
|
1514 | + public function setTime($hour, $minute, $second = 0, $microseconds = 0) |
|
1515 | + { |
|
1516 | + return parent::setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds); |
|
1517 | + } |
|
1518 | + |
|
1519 | + /** |
|
1520 | + * Set the instance's timestamp. |
|
1521 | + * |
|
1522 | + * Timestamp input can be given as int, float or a string containing one or more numbers. |
|
1523 | + * |
|
1524 | + * @param float|int|string $unixTimestamp |
|
1525 | + * |
|
1526 | + * @return static |
|
1527 | + */ |
|
1528 | + #[ReturnTypeWillChange] |
|
1529 | + public function setTimestamp($unixTimestamp) |
|
1530 | + { |
|
1531 | + [$timestamp, $microseconds] = self::getIntegerAndDecimalParts($unixTimestamp); |
|
1532 | + |
|
1533 | + return parent::setTimestamp((int) $timestamp)->setMicroseconds((int) $microseconds); |
|
1534 | + } |
|
1535 | + |
|
1536 | + /** |
|
1537 | + * Set the time by time string. |
|
1538 | + * |
|
1539 | + * @param string $time |
|
1540 | + * |
|
1541 | + * @return static |
|
1542 | + */ |
|
1543 | + public function setTimeFromTimeString($time) |
|
1544 | + { |
|
1545 | + if (!str_contains($time, ':')) { |
|
1546 | + $time .= ':0'; |
|
1547 | + } |
|
1548 | + |
|
1549 | + return $this->modify($time); |
|
1550 | + } |
|
1551 | + |
|
1552 | + /** |
|
1553 | + * @alias setTimezone |
|
1554 | + * |
|
1555 | + * @param DateTimeZone|string $value |
|
1556 | + * |
|
1557 | + * @return static |
|
1558 | + */ |
|
1559 | + public function timezone($value) |
|
1560 | + { |
|
1561 | + return $this->setTimezone($value); |
|
1562 | + } |
|
1563 | + |
|
1564 | + /** |
|
1565 | + * Set the timezone or returns the timezone name if no arguments passed. |
|
1566 | + * |
|
1567 | + * @param DateTimeZone|string $value |
|
1568 | + * |
|
1569 | + * @return static|string |
|
1570 | + */ |
|
1571 | + public function tz($value = null) |
|
1572 | + { |
|
1573 | + if (\func_num_args() < 1) { |
|
1574 | + return $this->tzName; |
|
1575 | + } |
|
1576 | + |
|
1577 | + return $this->setTimezone($value); |
|
1578 | + } |
|
1579 | + |
|
1580 | + /** |
|
1581 | + * Set the instance's timezone from a string or object. |
|
1582 | + * |
|
1583 | + * @param DateTimeZone|string $value |
|
1584 | + * |
|
1585 | + * @return static |
|
1586 | + */ |
|
1587 | + #[ReturnTypeWillChange] |
|
1588 | + public function setTimezone($value) |
|
1589 | + { |
|
1590 | + $tz = static::safeCreateDateTimeZone($value); |
|
1591 | + |
|
1592 | + if ($tz === false && !self::isStrictModeEnabled()) { |
|
1593 | + $tz = new CarbonTimeZone(); |
|
1594 | + } |
|
1595 | + |
|
1596 | + return parent::setTimezone($tz); |
|
1597 | + } |
|
1598 | + |
|
1599 | + /** |
|
1600 | + * Set the instance's timezone from a string or object and add/subtract the offset difference. |
|
1601 | + * |
|
1602 | + * @param DateTimeZone|string $value |
|
1603 | + * |
|
1604 | + * @return static |
|
1605 | + */ |
|
1606 | + public function shiftTimezone($value) |
|
1607 | + { |
|
1608 | + $dateTimeString = $this->format('Y-m-d H:i:s.u'); |
|
1609 | + |
|
1610 | + return $this |
|
1611 | + ->setTimezone($value) |
|
1612 | + ->modify($dateTimeString); |
|
1613 | + } |
|
1614 | + |
|
1615 | + /** |
|
1616 | + * Set the instance's timezone to UTC. |
|
1617 | + * |
|
1618 | + * @return static |
|
1619 | + */ |
|
1620 | + public function utc() |
|
1621 | + { |
|
1622 | + return $this->setTimezone('UTC'); |
|
1623 | + } |
|
1624 | + |
|
1625 | + /** |
|
1626 | + * Set the year, month, and date for this instance to that of the passed instance. |
|
1627 | + * |
|
1628 | + * @param Carbon|DateTimeInterface $date now if null |
|
1629 | + * |
|
1630 | + * @return static |
|
1631 | + */ |
|
1632 | + public function setDateFrom($date = null) |
|
1633 | + { |
|
1634 | + $date = $this->resolveCarbon($date); |
|
1635 | + |
|
1636 | + return $this->setDate($date->year, $date->month, $date->day); |
|
1637 | + } |
|
1638 | + |
|
1639 | + /** |
|
1640 | + * Set the hour, minute, second and microseconds for this instance to that of the passed instance. |
|
1641 | + * |
|
1642 | + * @param Carbon|DateTimeInterface $date now if null |
|
1643 | + * |
|
1644 | + * @return static |
|
1645 | + */ |
|
1646 | + public function setTimeFrom($date = null) |
|
1647 | + { |
|
1648 | + $date = $this->resolveCarbon($date); |
|
1649 | + |
|
1650 | + return $this->setTime($date->hour, $date->minute, $date->second, $date->microsecond); |
|
1651 | + } |
|
1652 | + |
|
1653 | + /** |
|
1654 | + * Set the date and time for this instance to that of the passed instance. |
|
1655 | + * |
|
1656 | + * @param Carbon|DateTimeInterface $date |
|
1657 | + * |
|
1658 | + * @return static |
|
1659 | + */ |
|
1660 | + public function setDateTimeFrom($date = null) |
|
1661 | + { |
|
1662 | + $date = $this->resolveCarbon($date); |
|
1663 | + |
|
1664 | + return $this->modify($date->rawFormat('Y-m-d H:i:s.u')); |
|
1665 | + } |
|
1666 | + |
|
1667 | + /** |
|
1668 | + * Get the days of the week |
|
1669 | + * |
|
1670 | + * @return array |
|
1671 | + */ |
|
1672 | + public static function getDays() |
|
1673 | + { |
|
1674 | + return static::$days; |
|
1675 | + } |
|
1676 | + |
|
1677 | + /////////////////////////////////////////////////////////////////// |
|
1678 | + /////////////////////// WEEK SPECIAL DAYS ///////////////////////// |
|
1679 | + /////////////////////////////////////////////////////////////////// |
|
1680 | + |
|
1681 | + private static function getFirstDayOfWeek(): int |
|
1682 | + { |
|
1683 | + return (int) static::getTranslationMessageWith( |
|
1684 | + static::getTranslator(), |
|
1685 | + 'first_day_of_week' |
|
1686 | + ); |
|
1687 | + } |
|
1688 | + |
|
1689 | + /** |
|
1690 | + * Get the first day of week |
|
1691 | + * |
|
1692 | + * @return int |
|
1693 | + */ |
|
1694 | + public static function getWeekStartsAt() |
|
1695 | + { |
|
1696 | + if (static::$weekStartsAt === static::WEEK_DAY_AUTO) { |
|
1697 | + return self::getFirstDayOfWeek(); |
|
1698 | + } |
|
1699 | + |
|
1700 | + return static::$weekStartsAt; |
|
1701 | + } |
|
1702 | + |
|
1703 | + /** |
|
1704 | + * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
1705 | + * Use $weekEndsAt optional parameter instead when using endOfWeek method. You can also use the |
|
1706 | + * 'first_day_of_week' locale setting to change the start of week according to current locale |
|
1707 | + * selected and implicitly the end of week. |
|
1708 | + * |
|
1709 | + * Set the first day of week |
|
1710 | + * |
|
1711 | + * @param int|string $day week start day (or 'auto' to get the first day of week from Carbon::getLocale() culture). |
|
1712 | + * |
|
1713 | + * @return void |
|
1714 | + */ |
|
1715 | + public static function setWeekStartsAt($day) |
|
1716 | + { |
|
1717 | + static::$weekStartsAt = $day === static::WEEK_DAY_AUTO ? $day : max(0, (7 + $day) % 7); |
|
1718 | + } |
|
1719 | + |
|
1720 | + /** |
|
1721 | + * Get the last day of week |
|
1722 | + * |
|
1723 | + * @return int |
|
1724 | + */ |
|
1725 | + public static function getWeekEndsAt() |
|
1726 | + { |
|
1727 | + if (static::$weekStartsAt === static::WEEK_DAY_AUTO) { |
|
1728 | + return (int) (static::DAYS_PER_WEEK - 1 + self::getFirstDayOfWeek()) % static::DAYS_PER_WEEK; |
|
1729 | + } |
|
1730 | + |
|
1731 | + return static::$weekEndsAt; |
|
1732 | + } |
|
1733 | + |
|
1734 | + /** |
|
1735 | + * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
1736 | + * Use $weekStartsAt optional parameter instead when using startOfWeek, floorWeek, ceilWeek |
|
1737 | + * or roundWeek method. You can also use the 'first_day_of_week' locale setting to change the |
|
1738 | + * start of week according to current locale selected and implicitly the end of week. |
|
1739 | + * |
|
1740 | + * Set the last day of week |
|
1741 | + * |
|
1742 | + * @param int|string $day week end day (or 'auto' to get the day before the first day of week |
|
1743 | + * from Carbon::getLocale() culture). |
|
1744 | + * |
|
1745 | + * @return void |
|
1746 | + */ |
|
1747 | + public static function setWeekEndsAt($day) |
|
1748 | + { |
|
1749 | + static::$weekEndsAt = $day === static::WEEK_DAY_AUTO ? $day : max(0, (7 + $day) % 7); |
|
1750 | + } |
|
1751 | + |
|
1752 | + /** |
|
1753 | + * Get weekend days |
|
1754 | + * |
|
1755 | + * @return array |
|
1756 | + */ |
|
1757 | + public static function getWeekendDays() |
|
1758 | + { |
|
1759 | + return static::$weekendDays; |
|
1760 | + } |
|
1761 | + |
|
1762 | + /** |
|
1763 | + * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
1764 | + * You should rather consider week-end is always saturday and sunday, and if you have some custom |
|
1765 | + * week-end days to handle, give to those days an other name and create a macro for them: |
|
1766 | + * |
|
1767 | + * ``` |
|
1768 | + * Carbon::macro('isDayOff', function ($date) { |
|
1769 | + * return $date->isSunday() || $date->isMonday(); |
|
1770 | + * }); |
|
1771 | + * Carbon::macro('isNotDayOff', function ($date) { |
|
1772 | + * return !$date->isDayOff(); |
|
1773 | + * }); |
|
1774 | + * if ($someDate->isDayOff()) ... |
|
1775 | + * if ($someDate->isNotDayOff()) ... |
|
1776 | + * // Add 5 not-off days |
|
1777 | + * $count = 5; |
|
1778 | + * while ($someDate->isDayOff() || ($count-- > 0)) { |
|
1779 | + * $someDate->addDay(); |
|
1780 | + * } |
|
1781 | + * ``` |
|
1782 | + * |
|
1783 | + * Set weekend days |
|
1784 | + * |
|
1785 | + * @param array $days |
|
1786 | + * |
|
1787 | + * @return void |
|
1788 | + */ |
|
1789 | + public static function setWeekendDays($days) |
|
1790 | + { |
|
1791 | + static::$weekendDays = $days; |
|
1792 | + } |
|
1793 | + |
|
1794 | + /** |
|
1795 | + * Determine if a time string will produce a relative date. |
|
1796 | + * |
|
1797 | + * @param string $time |
|
1798 | + * |
|
1799 | + * @return bool true if time match a relative date, false if absolute or invalid time string |
|
1800 | + */ |
|
1801 | + public static function hasRelativeKeywords($time) |
|
1802 | + { |
|
1803 | + if (!$time || strtotime($time) === false) { |
|
1804 | + return false; |
|
1805 | + } |
|
1806 | + |
|
1807 | + $date1 = new DateTime('2000-01-01T00:00:00Z'); |
|
1808 | + $date1->modify($time); |
|
1809 | + $date2 = new DateTime('2001-12-25T00:00:00Z'); |
|
1810 | + $date2->modify($time); |
|
1811 | + |
|
1812 | + return $date1 != $date2; |
|
1813 | + } |
|
1814 | + |
|
1815 | + /////////////////////////////////////////////////////////////////// |
|
1816 | + /////////////////////// STRING FORMATTING ///////////////////////// |
|
1817 | + /////////////////////////////////////////////////////////////////// |
|
1818 | + |
|
1819 | + /** |
|
1820 | + * @deprecated To avoid conflict between different third-party libraries, static setters should not be used. |
|
1821 | + * You should rather use UTF-8 language packages on every machine. |
|
1822 | + * |
|
1823 | + * Set if UTF8 will be used for localized date/time. |
|
1824 | + * |
|
1825 | + * @param bool $utf8 |
|
1826 | + */ |
|
1827 | + public static function setUtf8($utf8) |
|
1828 | + { |
|
1829 | + static::$utf8 = $utf8; |
|
1830 | + } |
|
1831 | + |
|
1832 | + /** |
|
1833 | + * Format the instance with the current locale. You can set the current |
|
1834 | + * locale using setlocale() https://php.net/setlocale. |
|
1835 | + * |
|
1836 | + * @deprecated It uses OS language package and strftime() which is deprecated since PHP 8.1. |
|
1837 | + * Use ->isoFormat() instead. |
|
1838 | + * Deprecated since 2.55.0 |
|
1839 | + * |
|
1840 | + * @param string $format |
|
1841 | + * |
|
1842 | + * @return string |
|
1843 | + */ |
|
1844 | + public function formatLocalized($format) |
|
1845 | + { |
|
1846 | + // Check for Windows to find and replace the %e modifier correctly. |
|
1847 | + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { |
|
1848 | + $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format); // @codeCoverageIgnore |
|
1849 | + } |
|
1850 | + |
|
1851 | + $time = strtotime($this->toDateTimeString()); |
|
1852 | + $formatted = ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) |
|
1853 | + ? strftime($format, $time) |
|
1854 | + : @strftime($format, $time); |
|
1855 | + |
|
1856 | + return static::$utf8 |
|
1857 | + ? ( |
|
1858 | + \function_exists('mb_convert_encoding') |
|
1859 | + ? mb_convert_encoding($formatted, 'UTF-8', mb_list_encodings()) |
|
1860 | + : mb_convert_encoding($formatted, 'UTF-8', 'ISO-8859-1') |
|
1861 | + ) |
|
1862 | + : $formatted; |
|
1863 | + } |
|
1864 | + |
|
1865 | + /** |
|
1866 | + * Returns list of locale formats for ISO formatting. |
|
1867 | + * |
|
1868 | + * @param string|null $locale current locale used if null |
|
1869 | + * |
|
1870 | + * @return array |
|
1871 | + */ |
|
1872 | + public function getIsoFormats($locale = null) |
|
1873 | + { |
|
1874 | + return [ |
|
1875 | + 'LT' => $this->getTranslationMessage('formats.LT', $locale, 'h:mm A'), |
|
1876 | + 'LTS' => $this->getTranslationMessage('formats.LTS', $locale, 'h:mm:ss A'), |
|
1877 | + 'L' => $this->getTranslationMessage('formats.L', $locale, 'MM/DD/YYYY'), |
|
1878 | + 'LL' => $this->getTranslationMessage('formats.LL', $locale, 'MMMM D, YYYY'), |
|
1879 | + 'LLL' => $this->getTranslationMessage('formats.LLL', $locale, 'MMMM D, YYYY h:mm A'), |
|
1880 | + 'LLLL' => $this->getTranslationMessage('formats.LLLL', $locale, 'dddd, MMMM D, YYYY h:mm A'), |
|
1881 | + ]; |
|
1882 | + } |
|
1883 | + |
|
1884 | + /** |
|
1885 | + * Returns list of calendar formats for ISO formatting. |
|
1886 | + * |
|
1887 | + * @param string|null $locale current locale used if null |
|
1888 | + * |
|
1889 | + * @return array |
|
1890 | + */ |
|
1891 | + public function getCalendarFormats($locale = null) |
|
1892 | + { |
|
1893 | + return [ |
|
1894 | + 'sameDay' => $this->getTranslationMessage('calendar.sameDay', $locale, '[Today at] LT'), |
|
1895 | + 'nextDay' => $this->getTranslationMessage('calendar.nextDay', $locale, '[Tomorrow at] LT'), |
|
1896 | + 'nextWeek' => $this->getTranslationMessage('calendar.nextWeek', $locale, 'dddd [at] LT'), |
|
1897 | + 'lastDay' => $this->getTranslationMessage('calendar.lastDay', $locale, '[Yesterday at] LT'), |
|
1898 | + 'lastWeek' => $this->getTranslationMessage('calendar.lastWeek', $locale, '[Last] dddd [at] LT'), |
|
1899 | + 'sameElse' => $this->getTranslationMessage('calendar.sameElse', $locale, 'L'), |
|
1900 | + ]; |
|
1901 | + } |
|
1902 | + |
|
1903 | + /** |
|
1904 | + * Returns list of locale units for ISO formatting. |
|
1905 | + * |
|
1906 | + * @return array |
|
1907 | + */ |
|
1908 | + public static function getIsoUnits() |
|
1909 | + { |
|
1910 | + static $units = null; |
|
1911 | + |
|
1912 | + if ($units === null) { |
|
1913 | + $units = [ |
|
1914 | + 'OD' => ['getAltNumber', ['day']], |
|
1915 | + 'OM' => ['getAltNumber', ['month']], |
|
1916 | + 'OY' => ['getAltNumber', ['year']], |
|
1917 | + 'OH' => ['getAltNumber', ['hour']], |
|
1918 | + 'Oh' => ['getAltNumber', ['h']], |
|
1919 | + 'Om' => ['getAltNumber', ['minute']], |
|
1920 | + 'Os' => ['getAltNumber', ['second']], |
|
1921 | + 'D' => 'day', |
|
1922 | + 'DD' => ['rawFormat', ['d']], |
|
1923 | + 'Do' => ['ordinal', ['day', 'D']], |
|
1924 | + 'd' => 'dayOfWeek', |
|
1925 | + 'dd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1926 | + return $date->getTranslatedMinDayName($originalFormat); |
|
1927 | + }, |
|
1928 | + 'ddd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1929 | + return $date->getTranslatedShortDayName($originalFormat); |
|
1930 | + }, |
|
1931 | + 'dddd' => function (CarbonInterface $date, $originalFormat = null) { |
|
1932 | + return $date->getTranslatedDayName($originalFormat); |
|
1933 | + }, |
|
1934 | + 'DDD' => 'dayOfYear', |
|
1935 | + 'DDDD' => ['getPaddedUnit', ['dayOfYear', 3]], |
|
1936 | + 'DDDo' => ['ordinal', ['dayOfYear', 'DDD']], |
|
1937 | + 'e' => ['weekday', []], |
|
1938 | + 'E' => 'dayOfWeekIso', |
|
1939 | + 'H' => ['rawFormat', ['G']], |
|
1940 | + 'HH' => ['rawFormat', ['H']], |
|
1941 | + 'h' => ['rawFormat', ['g']], |
|
1942 | + 'hh' => ['rawFormat', ['h']], |
|
1943 | + 'k' => 'noZeroHour', |
|
1944 | + 'kk' => ['getPaddedUnit', ['noZeroHour']], |
|
1945 | + 'hmm' => ['rawFormat', ['gi']], |
|
1946 | + 'hmmss' => ['rawFormat', ['gis']], |
|
1947 | + 'Hmm' => ['rawFormat', ['Gi']], |
|
1948 | + 'Hmmss' => ['rawFormat', ['Gis']], |
|
1949 | + 'm' => 'minute', |
|
1950 | + 'mm' => ['rawFormat', ['i']], |
|
1951 | + 'a' => 'meridiem', |
|
1952 | + 'A' => 'upperMeridiem', |
|
1953 | + 's' => 'second', |
|
1954 | + 'ss' => ['getPaddedUnit', ['second']], |
|
1955 | + 'S' => function (CarbonInterface $date) { |
|
1956 | + return (string) floor($date->micro / 100000); |
|
1957 | + }, |
|
1958 | + 'SS' => function (CarbonInterface $date) { |
|
1959 | + return str_pad((string) floor($date->micro / 10000), 2, '0', STR_PAD_LEFT); |
|
1960 | + }, |
|
1961 | + 'SSS' => function (CarbonInterface $date) { |
|
1962 | + return str_pad((string) floor($date->micro / 1000), 3, '0', STR_PAD_LEFT); |
|
1963 | + }, |
|
1964 | + 'SSSS' => function (CarbonInterface $date) { |
|
1965 | + return str_pad((string) floor($date->micro / 100), 4, '0', STR_PAD_LEFT); |
|
1966 | + }, |
|
1967 | + 'SSSSS' => function (CarbonInterface $date) { |
|
1968 | + return str_pad((string) floor($date->micro / 10), 5, '0', STR_PAD_LEFT); |
|
1969 | + }, |
|
1970 | + 'SSSSSS' => ['getPaddedUnit', ['micro', 6]], |
|
1971 | + 'SSSSSSS' => function (CarbonInterface $date) { |
|
1972 | + return str_pad((string) floor($date->micro * 10), 7, '0', STR_PAD_LEFT); |
|
1973 | + }, |
|
1974 | + 'SSSSSSSS' => function (CarbonInterface $date) { |
|
1975 | + return str_pad((string) floor($date->micro * 100), 8, '0', STR_PAD_LEFT); |
|
1976 | + }, |
|
1977 | + 'SSSSSSSSS' => function (CarbonInterface $date) { |
|
1978 | + return str_pad((string) floor($date->micro * 1000), 9, '0', STR_PAD_LEFT); |
|
1979 | + }, |
|
1980 | + 'M' => 'month', |
|
1981 | + 'MM' => ['rawFormat', ['m']], |
|
1982 | + 'MMM' => function (CarbonInterface $date, $originalFormat = null) { |
|
1983 | + $month = $date->getTranslatedShortMonthName($originalFormat); |
|
1984 | + $suffix = $date->getTranslationMessage('mmm_suffix'); |
|
1985 | + if ($suffix && $month !== $date->monthName) { |
|
1986 | + $month .= $suffix; |
|
1987 | + } |
|
1988 | + |
|
1989 | + return $month; |
|
1990 | + }, |
|
1991 | + 'MMMM' => function (CarbonInterface $date, $originalFormat = null) { |
|
1992 | + return $date->getTranslatedMonthName($originalFormat); |
|
1993 | + }, |
|
1994 | + 'Mo' => ['ordinal', ['month', 'M']], |
|
1995 | + 'Q' => 'quarter', |
|
1996 | + 'Qo' => ['ordinal', ['quarter', 'M']], |
|
1997 | + 'G' => 'isoWeekYear', |
|
1998 | + 'GG' => ['getPaddedUnit', ['isoWeekYear']], |
|
1999 | + 'GGG' => ['getPaddedUnit', ['isoWeekYear', 3]], |
|
2000 | + 'GGGG' => ['getPaddedUnit', ['isoWeekYear', 4]], |
|
2001 | + 'GGGGG' => ['getPaddedUnit', ['isoWeekYear', 5]], |
|
2002 | + 'g' => 'weekYear', |
|
2003 | + 'gg' => ['getPaddedUnit', ['weekYear']], |
|
2004 | + 'ggg' => ['getPaddedUnit', ['weekYear', 3]], |
|
2005 | + 'gggg' => ['getPaddedUnit', ['weekYear', 4]], |
|
2006 | + 'ggggg' => ['getPaddedUnit', ['weekYear', 5]], |
|
2007 | + 'W' => 'isoWeek', |
|
2008 | + 'WW' => ['getPaddedUnit', ['isoWeek']], |
|
2009 | + 'Wo' => ['ordinal', ['isoWeek', 'W']], |
|
2010 | + 'w' => 'week', |
|
2011 | + 'ww' => ['getPaddedUnit', ['week']], |
|
2012 | + 'wo' => ['ordinal', ['week', 'w']], |
|
2013 | + 'x' => ['valueOf', []], |
|
2014 | + 'X' => 'timestamp', |
|
2015 | + 'Y' => 'year', |
|
2016 | + 'YY' => ['rawFormat', ['y']], |
|
2017 | + 'YYYY' => ['getPaddedUnit', ['year', 4]], |
|
2018 | + 'YYYYY' => ['getPaddedUnit', ['year', 5]], |
|
2019 | + 'YYYYYY' => function (CarbonInterface $date) { |
|
2020 | + return ($date->year < 0 ? '' : '+').$date->getPaddedUnit('year', 6); |
|
2021 | + }, |
|
2022 | + 'z' => ['rawFormat', ['T']], |
|
2023 | + 'zz' => 'tzName', |
|
2024 | + 'Z' => ['getOffsetString', []], |
|
2025 | + 'ZZ' => ['getOffsetString', ['']], |
|
2026 | + ]; |
|
2027 | + } |
|
2028 | + |
|
2029 | + return $units; |
|
2030 | + } |
|
2031 | + |
|
2032 | + /** |
|
2033 | + * Returns a unit of the instance padded with 0 by default or any other string if specified. |
|
2034 | + * |
|
2035 | + * @param string $unit Carbon unit name |
|
2036 | + * @param int $length Length of the output (2 by default) |
|
2037 | + * @param string $padString String to use for padding ("0" by default) |
|
2038 | + * @param int $padType Side(s) to pad (STR_PAD_LEFT by default) |
|
2039 | + * |
|
2040 | + * @return string |
|
2041 | + */ |
|
2042 | + public function getPaddedUnit($unit, $length = 2, $padString = '0', $padType = STR_PAD_LEFT) |
|
2043 | + { |
|
2044 | + return ($this->$unit < 0 ? '-' : '').str_pad((string) abs($this->$unit), $length, $padString, $padType); |
|
2045 | + } |
|
2046 | + |
|
2047 | + /** |
|
2048 | + * Return a property with its ordinal. |
|
2049 | + * |
|
2050 | + * @param string $key |
|
2051 | + * @param string|null $period |
|
2052 | + * |
|
2053 | + * @return string |
|
2054 | + */ |
|
2055 | + public function ordinal(string $key, ?string $period = null): string |
|
2056 | + { |
|
2057 | + $number = $this->$key; |
|
2058 | + $result = $this->translate('ordinal', [ |
|
2059 | + ':number' => $number, |
|
2060 | + ':period' => (string) $period, |
|
2061 | + ]); |
|
2062 | + |
|
2063 | + return (string) ($result === 'ordinal' ? $number : $result); |
|
2064 | + } |
|
2065 | + |
|
2066 | + /** |
|
2067 | + * Return the meridiem of the current time in the current locale. |
|
2068 | + * |
|
2069 | + * @param bool $isLower if true, returns lowercase variant if available in the current locale. |
|
2070 | + * |
|
2071 | + * @return string |
|
2072 | + */ |
|
2073 | + public function meridiem(bool $isLower = false): string |
|
2074 | + { |
|
2075 | + $hour = $this->hour; |
|
2076 | + $index = $hour < 12 ? 0 : 1; |
|
2077 | + |
|
2078 | + if ($isLower) { |
|
2079 | + $key = 'meridiem.'.($index + 2); |
|
2080 | + $result = $this->translate($key); |
|
2081 | + |
|
2082 | + if ($result !== $key) { |
|
2083 | + return $result; |
|
2084 | + } |
|
2085 | + } |
|
2086 | + |
|
2087 | + $key = "meridiem.$index"; |
|
2088 | + $result = $this->translate($key); |
|
2089 | + if ($result === $key) { |
|
2090 | + $result = $this->translate('meridiem', [ |
|
2091 | + ':hour' => $this->hour, |
|
2092 | + ':minute' => $this->minute, |
|
2093 | + ':isLower' => $isLower, |
|
2094 | + ]); |
|
2095 | + |
|
2096 | + if ($result === 'meridiem') { |
|
2097 | + return $isLower ? $this->latinMeridiem : $this->latinUpperMeridiem; |
|
2098 | + } |
|
2099 | + } elseif ($isLower) { |
|
2100 | + $result = mb_strtolower($result); |
|
2101 | + } |
|
2102 | + |
|
2103 | + return $result; |
|
2104 | + } |
|
2105 | + |
|
2106 | + /** |
|
2107 | + * Returns the alternative number for a given date property if available in the current locale. |
|
2108 | + * |
|
2109 | + * @param string $key date property |
|
2110 | + * |
|
2111 | + * @return string |
|
2112 | + */ |
|
2113 | + public function getAltNumber(string $key): string |
|
2114 | + { |
|
2115 | + return $this->translateNumber(\strlen($key) > 1 ? $this->$key : $this->rawFormat('h')); |
|
2116 | + } |
|
2117 | + |
|
2118 | + /** |
|
2119 | + * Format in the current language using ISO replacement patterns. |
|
2120 | + * |
|
2121 | + * @param string $format |
|
2122 | + * @param string|null $originalFormat provide context if a chunk has been passed alone |
|
2123 | + * |
|
2124 | + * @return string |
|
2125 | + */ |
|
2126 | + public function isoFormat(string $format, ?string $originalFormat = null): string |
|
2127 | + { |
|
2128 | + $result = ''; |
|
2129 | + $length = mb_strlen($format); |
|
2130 | + $originalFormat = $originalFormat ?: $format; |
|
2131 | + $inEscaped = false; |
|
2132 | + $formats = null; |
|
2133 | + $units = null; |
|
2134 | + |
|
2135 | + for ($i = 0; $i < $length; $i++) { |
|
2136 | + $char = mb_substr($format, $i, 1); |
|
2137 | + |
|
2138 | + if ($char === '\\') { |
|
2139 | + $result .= mb_substr($format, ++$i, 1); |
|
2140 | + |
|
2141 | + continue; |
|
2142 | + } |
|
2143 | + |
|
2144 | + if ($char === '[' && !$inEscaped) { |
|
2145 | + $inEscaped = true; |
|
2146 | + |
|
2147 | + continue; |
|
2148 | + } |
|
2149 | + |
|
2150 | + if ($char === ']' && $inEscaped) { |
|
2151 | + $inEscaped = false; |
|
2152 | + |
|
2153 | + continue; |
|
2154 | + } |
|
2155 | + |
|
2156 | + if ($inEscaped) { |
|
2157 | + $result .= $char; |
|
2158 | + |
|
2159 | + continue; |
|
2160 | + } |
|
2161 | + |
|
2162 | + $input = mb_substr($format, $i); |
|
2163 | + |
|
2164 | + if (preg_match('/^(LTS|LT|[Ll]{1,4})/', $input, $match)) { |
|
2165 | + if ($formats === null) { |
|
2166 | + $formats = $this->getIsoFormats(); |
|
2167 | + } |
|
2168 | + |
|
2169 | + $code = $match[0]; |
|
2170 | + $sequence = $formats[$code] ?? preg_replace_callback( |
|
2171 | + '/MMMM|MM|DD|dddd/', |
|
2172 | + function ($code) { |
|
2173 | + return mb_substr($code[0], 1); |
|
2174 | + }, |
|
2175 | + $formats[strtoupper($code)] ?? '' |
|
2176 | + ); |
|
2177 | + $rest = mb_substr($format, $i + mb_strlen($code)); |
|
2178 | + $format = mb_substr($format, 0, $i).$sequence.$rest; |
|
2179 | + $length = mb_strlen($format); |
|
2180 | + $input = $sequence.$rest; |
|
2181 | + } |
|
2182 | + |
|
2183 | + if (preg_match('/^'.CarbonInterface::ISO_FORMAT_REGEXP.'/', $input, $match)) { |
|
2184 | + $code = $match[0]; |
|
2185 | + |
|
2186 | + if ($units === null) { |
|
2187 | + $units = static::getIsoUnits(); |
|
2188 | + } |
|
2189 | + |
|
2190 | + $sequence = $units[$code] ?? ''; |
|
2191 | + |
|
2192 | + if ($sequence instanceof Closure) { |
|
2193 | + $sequence = $sequence($this, $originalFormat); |
|
2194 | + } elseif (\is_array($sequence)) { |
|
2195 | + try { |
|
2196 | + $sequence = $this->{$sequence[0]}(...$sequence[1]); |
|
2197 | + } catch (ReflectionException | InvalidArgumentException | BadMethodCallException $e) { |
|
2198 | + $sequence = ''; |
|
2199 | + } |
|
2200 | + } elseif (\is_string($sequence)) { |
|
2201 | + $sequence = $this->$sequence ?? $code; |
|
2202 | + } |
|
2203 | + |
|
2204 | + $format = mb_substr($format, 0, $i).$sequence.mb_substr($format, $i + mb_strlen($code)); |
|
2205 | + $i += mb_strlen((string) $sequence) - 1; |
|
2206 | + $length = mb_strlen($format); |
|
2207 | + $char = $sequence; |
|
2208 | + } |
|
2209 | + |
|
2210 | + $result .= $char; |
|
2211 | + } |
|
2212 | + |
|
2213 | + return $result; |
|
2214 | + } |
|
2215 | + |
|
2216 | + /** |
|
2217 | + * List of replacements from date() format to isoFormat(). |
|
2218 | + * |
|
2219 | + * @return array |
|
2220 | + */ |
|
2221 | + public static function getFormatsToIsoReplacements() |
|
2222 | + { |
|
2223 | + static $replacements = null; |
|
2224 | + |
|
2225 | + if ($replacements === null) { |
|
2226 | + $replacements = [ |
|
2227 | + 'd' => true, |
|
2228 | + 'D' => 'ddd', |
|
2229 | + 'j' => true, |
|
2230 | + 'l' => 'dddd', |
|
2231 | + 'N' => true, |
|
2232 | + 'S' => function ($date) { |
|
2233 | + $day = $date->rawFormat('j'); |
|
2234 | + |
|
2235 | + return str_replace((string) $day, '', $date->isoFormat('Do')); |
|
2236 | + }, |
|
2237 | + 'w' => true, |
|
2238 | + 'z' => true, |
|
2239 | + 'W' => true, |
|
2240 | + 'F' => 'MMMM', |
|
2241 | + 'm' => true, |
|
2242 | + 'M' => 'MMM', |
|
2243 | + 'n' => true, |
|
2244 | + 't' => true, |
|
2245 | + 'L' => true, |
|
2246 | + 'o' => true, |
|
2247 | + 'Y' => true, |
|
2248 | + 'y' => true, |
|
2249 | + 'a' => 'a', |
|
2250 | + 'A' => 'A', |
|
2251 | + 'B' => true, |
|
2252 | + 'g' => true, |
|
2253 | + 'G' => true, |
|
2254 | + 'h' => true, |
|
2255 | + 'H' => true, |
|
2256 | + 'i' => true, |
|
2257 | + 's' => true, |
|
2258 | + 'u' => true, |
|
2259 | + 'v' => true, |
|
2260 | + 'E' => true, |
|
2261 | + 'I' => true, |
|
2262 | + 'O' => true, |
|
2263 | + 'P' => true, |
|
2264 | + 'Z' => true, |
|
2265 | + 'c' => true, |
|
2266 | + 'r' => true, |
|
2267 | + 'U' => true, |
|
2268 | + ]; |
|
2269 | + } |
|
2270 | + |
|
2271 | + return $replacements; |
|
2272 | + } |
|
2273 | + |
|
2274 | + /** |
|
2275 | + * Format as ->format() do (using date replacements patterns from https://php.net/manual/en/function.date.php) |
|
2276 | + * but translate words whenever possible (months, day names, etc.) using the current locale. |
|
2277 | + * |
|
2278 | + * @param string $format |
|
2279 | + * |
|
2280 | + * @return string |
|
2281 | + */ |
|
2282 | + public function translatedFormat(string $format): string |
|
2283 | + { |
|
2284 | + $replacements = static::getFormatsToIsoReplacements(); |
|
2285 | + $context = ''; |
|
2286 | + $isoFormat = ''; |
|
2287 | + $length = mb_strlen($format); |
|
2288 | + |
|
2289 | + for ($i = 0; $i < $length; $i++) { |
|
2290 | + $char = mb_substr($format, $i, 1); |
|
2291 | + |
|
2292 | + if ($char === '\\') { |
|
2293 | + $replacement = mb_substr($format, $i, 2); |
|
2294 | + $isoFormat .= $replacement; |
|
2295 | + $i++; |
|
2296 | + |
|
2297 | + continue; |
|
2298 | + } |
|
2299 | + |
|
2300 | + if (!isset($replacements[$char])) { |
|
2301 | + $replacement = preg_match('/^[A-Za-z]$/', $char) ? "\\$char" : $char; |
|
2302 | + $isoFormat .= $replacement; |
|
2303 | + $context .= $replacement; |
|
2304 | + |
|
2305 | + continue; |
|
2306 | + } |
|
2307 | + |
|
2308 | + $replacement = $replacements[$char]; |
|
2309 | + |
|
2310 | + if ($replacement === true) { |
|
2311 | + static $contextReplacements = null; |
|
2312 | + |
|
2313 | + if ($contextReplacements === null) { |
|
2314 | + $contextReplacements = [ |
|
2315 | + 'm' => 'MM', |
|
2316 | + 'd' => 'DD', |
|
2317 | + 't' => 'D', |
|
2318 | + 'j' => 'D', |
|
2319 | + 'N' => 'e', |
|
2320 | + 'w' => 'e', |
|
2321 | + 'n' => 'M', |
|
2322 | + 'o' => 'YYYY', |
|
2323 | + 'Y' => 'YYYY', |
|
2324 | + 'y' => 'YY', |
|
2325 | + 'g' => 'h', |
|
2326 | + 'G' => 'H', |
|
2327 | + 'h' => 'hh', |
|
2328 | + 'H' => 'HH', |
|
2329 | + 'i' => 'mm', |
|
2330 | + 's' => 'ss', |
|
2331 | + ]; |
|
2332 | + } |
|
2333 | + |
|
2334 | + $isoFormat .= '['.$this->rawFormat($char).']'; |
|
2335 | + $context .= $contextReplacements[$char] ?? ' '; |
|
2336 | + |
|
2337 | + continue; |
|
2338 | + } |
|
2339 | + |
|
2340 | + if ($replacement instanceof Closure) { |
|
2341 | + $replacement = '['.$replacement($this).']'; |
|
2342 | + $isoFormat .= $replacement; |
|
2343 | + $context .= $replacement; |
|
2344 | + |
|
2345 | + continue; |
|
2346 | + } |
|
2347 | + |
|
2348 | + $isoFormat .= $replacement; |
|
2349 | + $context .= $replacement; |
|
2350 | + } |
|
2351 | + |
|
2352 | + return $this->isoFormat($isoFormat, $context); |
|
2353 | + } |
|
2354 | + |
|
2355 | + /** |
|
2356 | + * Returns the offset hour and minute formatted with +/- and a given separator (":" by default). |
|
2357 | + * For example, if the time zone is 9 hours 30 minutes, you'll get "+09:30", with "@@" as first |
|
2358 | + * argument, "+09@@30", with "" as first argument, "+0930". Negative offset will return something |
|
2359 | + * like "-12:00". |
|
2360 | + * |
|
2361 | + * @param string $separator string to place between hours and minutes (":" by default) |
|
2362 | + * |
|
2363 | + * @return string |
|
2364 | + */ |
|
2365 | + public function getOffsetString($separator = ':') |
|
2366 | + { |
|
2367 | + $second = $this->getOffset(); |
|
2368 | + $symbol = $second < 0 ? '-' : '+'; |
|
2369 | + $minute = abs($second) / static::SECONDS_PER_MINUTE; |
|
2370 | + $hour = str_pad((string) floor($minute / static::MINUTES_PER_HOUR), 2, '0', STR_PAD_LEFT); |
|
2371 | + $minute = str_pad((string) (((int) $minute) % static::MINUTES_PER_HOUR), 2, '0', STR_PAD_LEFT); |
|
2372 | + |
|
2373 | + return "$symbol$hour$separator$minute"; |
|
2374 | + } |
|
2375 | + |
|
2376 | + protected static function executeStaticCallable($macro, ...$parameters) |
|
2377 | + { |
|
2378 | + return static::bindMacroContext(null, function () use (&$macro, &$parameters) { |
|
2379 | + if ($macro instanceof Closure) { |
|
2380 | + $boundMacro = @Closure::bind($macro, null, static::class); |
|
2381 | + |
|
2382 | + return ($boundMacro ?: $macro)(...$parameters); |
|
2383 | + } |
|
2384 | + |
|
2385 | + return $macro(...$parameters); |
|
2386 | + }); |
|
2387 | + } |
|
2388 | + |
|
2389 | + /** |
|
2390 | + * Dynamically handle calls to the class. |
|
2391 | + * |
|
2392 | + * @param string $method magic method name called |
|
2393 | + * @param array $parameters parameters list |
|
2394 | + * |
|
2395 | + * @throws BadMethodCallException |
|
2396 | + * |
|
2397 | + * @return mixed |
|
2398 | + */ |
|
2399 | + public static function __callStatic($method, $parameters) |
|
2400 | + { |
|
2401 | + if (!static::hasMacro($method)) { |
|
2402 | + foreach (static::getGenericMacros() as $callback) { |
|
2403 | + try { |
|
2404 | + return static::executeStaticCallable($callback, $method, ...$parameters); |
|
2405 | + } catch (BadMethodCallException $exception) { |
|
2406 | + continue; |
|
2407 | + } |
|
2408 | + } |
|
2409 | + if (static::isStrictModeEnabled()) { |
|
2410 | + throw new UnknownMethodException(sprintf('%s::%s', static::class, $method)); |
|
2411 | + } |
|
2412 | + |
|
2413 | + return null; |
|
2414 | + } |
|
2415 | + |
|
2416 | + return static::executeStaticCallable(static::$globalMacros[$method], ...$parameters); |
|
2417 | + } |
|
2418 | + |
|
2419 | + /** |
|
2420 | + * Set specified unit to new given value. |
|
2421 | + * |
|
2422 | + * @param string $unit year, month, day, hour, minute, second or microsecond |
|
2423 | + * @param int $value new value for given unit |
|
2424 | + * |
|
2425 | + * @return static |
|
2426 | + */ |
|
2427 | + public function setUnit($unit, $value = null) |
|
2428 | + { |
|
2429 | + $unit = static::singularUnit($unit); |
|
2430 | + $dateUnits = ['year', 'month', 'day']; |
|
2431 | + if (\in_array($unit, $dateUnits)) { |
|
2432 | + return $this->setDate(...array_map(function ($name) use ($unit, $value) { |
|
2433 | + return (int) ($name === $unit ? $value : $this->$name); |
|
2434 | + }, $dateUnits)); |
|
2435 | + } |
|
2436 | + |
|
2437 | + $units = ['hour', 'minute', 'second', 'micro']; |
|
2438 | + if ($unit === 'millisecond' || $unit === 'milli') { |
|
2439 | + $value *= 1000; |
|
2440 | + $unit = 'micro'; |
|
2441 | + } elseif ($unit === 'microsecond') { |
|
2442 | + $unit = 'micro'; |
|
2443 | + } |
|
2444 | + |
|
2445 | + return $this->setTime(...array_map(function ($name) use ($unit, $value) { |
|
2446 | + return (int) ($name === $unit ? $value : $this->$name); |
|
2447 | + }, $units)); |
|
2448 | + } |
|
2449 | + |
|
2450 | + /** |
|
2451 | + * Returns standardized singular of a given singular/plural unit name (in English). |
|
2452 | + * |
|
2453 | + * @param string $unit |
|
2454 | + * |
|
2455 | + * @return string |
|
2456 | + */ |
|
2457 | + public static function singularUnit(string $unit): string |
|
2458 | + { |
|
2459 | + $unit = rtrim(mb_strtolower($unit), 's'); |
|
2460 | + |
|
2461 | + if ($unit === 'centurie') { |
|
2462 | + return 'century'; |
|
2463 | + } |
|
2464 | + |
|
2465 | + if ($unit === 'millennia') { |
|
2466 | + return 'millennium'; |
|
2467 | + } |
|
2468 | + |
|
2469 | + return $unit; |
|
2470 | + } |
|
2471 | + |
|
2472 | + /** |
|
2473 | + * Returns standardized plural of a given singular/plural unit name (in English). |
|
2474 | + * |
|
2475 | + * @param string $unit |
|
2476 | + * |
|
2477 | + * @return string |
|
2478 | + */ |
|
2479 | + public static function pluralUnit(string $unit): string |
|
2480 | + { |
|
2481 | + $unit = rtrim(strtolower($unit), 's'); |
|
2482 | + |
|
2483 | + if ($unit === 'century') { |
|
2484 | + return 'centuries'; |
|
2485 | + } |
|
2486 | + |
|
2487 | + if ($unit === 'millennium' || $unit === 'millennia') { |
|
2488 | + return 'millennia'; |
|
2489 | + } |
|
2490 | + |
|
2491 | + return "{$unit}s"; |
|
2492 | + } |
|
2493 | + |
|
2494 | + protected function executeCallable($macro, ...$parameters) |
|
2495 | + { |
|
2496 | + if ($macro instanceof Closure) { |
|
2497 | + $boundMacro = @$macro->bindTo($this, static::class) ?: @$macro->bindTo(null, static::class); |
|
2498 | + |
|
2499 | + return ($boundMacro ?: $macro)(...$parameters); |
|
2500 | + } |
|
2501 | + |
|
2502 | + return $macro(...$parameters); |
|
2503 | + } |
|
2504 | + |
|
2505 | + protected function executeCallableWithContext($macro, ...$parameters) |
|
2506 | + { |
|
2507 | + return static::bindMacroContext($this, function () use (&$macro, &$parameters) { |
|
2508 | + return $this->executeCallable($macro, ...$parameters); |
|
2509 | + }); |
|
2510 | + } |
|
2511 | + |
|
2512 | + protected static function getGenericMacros() |
|
2513 | + { |
|
2514 | + foreach (static::$globalGenericMacros as $list) { |
|
2515 | + foreach ($list as $macro) { |
|
2516 | + yield $macro; |
|
2517 | + } |
|
2518 | + } |
|
2519 | + } |
|
2520 | + |
|
2521 | + /** |
|
2522 | + * Dynamically handle calls to the class. |
|
2523 | + * |
|
2524 | + * @param string $method magic method name called |
|
2525 | + * @param array $parameters parameters list |
|
2526 | + * |
|
2527 | + * @throws UnknownMethodException|BadMethodCallException|ReflectionException|Throwable |
|
2528 | + * |
|
2529 | + * @return mixed |
|
2530 | + */ |
|
2531 | + public function __call($method, $parameters) |
|
2532 | + { |
|
2533 | + $diffSizes = [ |
|
2534 | + // @mode diffForHumans |
|
2535 | + 'short' => true, |
|
2536 | + // @mode diffForHumans |
|
2537 | + 'long' => false, |
|
2538 | + ]; |
|
2539 | + $diffSyntaxModes = [ |
|
2540 | + // @call diffForHumans |
|
2541 | + 'Absolute' => CarbonInterface::DIFF_ABSOLUTE, |
|
2542 | + // @call diffForHumans |
|
2543 | + 'Relative' => CarbonInterface::DIFF_RELATIVE_AUTO, |
|
2544 | + // @call diffForHumans |
|
2545 | + 'RelativeToNow' => CarbonInterface::DIFF_RELATIVE_TO_NOW, |
|
2546 | + // @call diffForHumans |
|
2547 | + 'RelativeToOther' => CarbonInterface::DIFF_RELATIVE_TO_OTHER, |
|
2548 | + ]; |
|
2549 | + $sizePattern = implode('|', array_keys($diffSizes)); |
|
2550 | + $syntaxPattern = implode('|', array_keys($diffSyntaxModes)); |
|
2551 | + |
|
2552 | + if (preg_match("/^(?<size>$sizePattern)(?<syntax>$syntaxPattern)DiffForHumans$/", $method, $match)) { |
|
2553 | + $dates = array_filter($parameters, function ($parameter) { |
|
2554 | + return $parameter instanceof DateTimeInterface; |
|
2555 | + }); |
|
2556 | + $other = null; |
|
2557 | + |
|
2558 | + if (\count($dates)) { |
|
2559 | + $key = key($dates); |
|
2560 | + $other = current($dates); |
|
2561 | + array_splice($parameters, $key, 1); |
|
2562 | + } |
|
2563 | + |
|
2564 | + return $this->diffForHumans($other, $diffSyntaxModes[$match['syntax']], $diffSizes[$match['size']], ...$parameters); |
|
2565 | + } |
|
2566 | + |
|
2567 | + $roundedValue = $this->callRoundMethod($method, $parameters); |
|
2568 | + |
|
2569 | + if ($roundedValue !== null) { |
|
2570 | + return $roundedValue; |
|
2571 | + } |
|
2572 | + |
|
2573 | + $unit = rtrim($method, 's'); |
|
2574 | + |
|
2575 | + if (str_starts_with($unit, 'is')) { |
|
2576 | + $word = substr($unit, 2); |
|
2577 | + |
|
2578 | + if (\in_array($word, static::$days, true)) { |
|
2579 | + return $this->isDayOfWeek($word); |
|
2580 | + } |
|
2581 | + |
|
2582 | + switch ($word) { |
|
2583 | + // @call is Check if the current instance has UTC timezone. (Both isUtc and isUTC cases are valid.) |
|
2584 | + case 'Utc': |
|
2585 | + case 'UTC': |
|
2586 | + return $this->utc; |
|
2587 | + // @call is Check if the current instance has non-UTC timezone. |
|
2588 | + case 'Local': |
|
2589 | + return $this->local; |
|
2590 | + // @call is Check if the current instance is a valid date. |
|
2591 | + case 'Valid': |
|
2592 | + return $this->year !== 0; |
|
2593 | + // @call is Check if the current instance is in a daylight saving time. |
|
2594 | + case 'DST': |
|
2595 | + return $this->dst; |
|
2596 | + } |
|
2597 | + } |
|
2598 | + |
|
2599 | + $action = substr($unit, 0, 3); |
|
2600 | + $overflow = null; |
|
2601 | + |
|
2602 | + if ($action === 'set') { |
|
2603 | + $unit = strtolower(substr($unit, 3)); |
|
2604 | + } |
|
2605 | + |
|
2606 | + if (\in_array($unit, static::$units, true)) { |
|
2607 | + return $this->setUnit($unit, ...$parameters); |
|
2608 | + } |
|
2609 | + |
|
2610 | + if ($action === 'add' || $action === 'sub') { |
|
2611 | + $unit = substr($unit, 3); |
|
2612 | + |
|
2613 | + if (str_starts_with($unit, 'Real')) { |
|
2614 | + $unit = static::singularUnit(substr($unit, 4)); |
|
2615 | + |
|
2616 | + return $this->{"{$action}RealUnit"}($unit, ...$parameters); |
|
2617 | + } |
|
2618 | + |
|
2619 | + if (preg_match('/^(Month|Quarter|Year|Decade|Century|Centurie|Millennium|Millennia)s?(No|With|Without|WithNo)Overflow$/', $unit, $match)) { |
|
2620 | + $unit = $match[1]; |
|
2621 | + $overflow = $match[2] === 'With'; |
|
2622 | + } |
|
2623 | + |
|
2624 | + $unit = static::singularUnit($unit); |
|
2625 | + } |
|
2626 | + |
|
2627 | + if (static::isModifiableUnit($unit)) { |
|
2628 | + return $this->{"{$action}Unit"}($unit, $parameters[0] ?? 1, $overflow); |
|
2629 | + } |
|
2630 | + |
|
2631 | + $sixFirstLetters = substr($unit, 0, 6); |
|
2632 | + $factor = -1; |
|
2633 | + |
|
2634 | + if ($sixFirstLetters === 'isLast') { |
|
2635 | + $sixFirstLetters = 'isNext'; |
|
2636 | + $factor = 1; |
|
2637 | + } |
|
2638 | + |
|
2639 | + if ($sixFirstLetters === 'isNext') { |
|
2640 | + $lowerUnit = strtolower(substr($unit, 6)); |
|
2641 | + |
|
2642 | + if (static::isModifiableUnit($lowerUnit)) { |
|
2643 | + return $this->copy()->addUnit($lowerUnit, $factor, false)->isSameUnit($lowerUnit, ...$parameters); |
|
2644 | + } |
|
2645 | + } |
|
2646 | + |
|
2647 | + if ($sixFirstLetters === 'isSame') { |
|
2648 | + try { |
|
2649 | + return $this->isSameUnit(strtolower(substr($unit, 6)), ...$parameters); |
|
2650 | + } catch (BadComparisonUnitException $exception) { |
|
2651 | + // Try next |
|
2652 | + } |
|
2653 | + } |
|
2654 | + |
|
2655 | + if (str_starts_with($unit, 'isCurrent')) { |
|
2656 | + try { |
|
2657 | + return $this->isCurrentUnit(strtolower(substr($unit, 9))); |
|
2658 | + } catch (BadComparisonUnitException | BadMethodCallException $exception) { |
|
2659 | + // Try next |
|
2660 | + } |
|
2661 | + } |
|
2662 | + |
|
2663 | + if (str_ends_with($method, 'Until')) { |
|
2664 | + try { |
|
2665 | + $unit = static::singularUnit(substr($method, 0, -5)); |
|
2666 | + |
|
2667 | + return $this->range($parameters[0] ?? $this, $parameters[1] ?? 1, $unit); |
|
2668 | + } catch (InvalidArgumentException $exception) { |
|
2669 | + // Try macros |
|
2670 | + } |
|
2671 | + } |
|
2672 | + |
|
2673 | + return static::bindMacroContext($this, function () use (&$method, &$parameters) { |
|
2674 | + $macro = $this->getLocalMacro($method); |
|
2675 | + |
|
2676 | + if (!$macro) { |
|
2677 | + foreach ([$this->localGenericMacros ?: [], static::getGenericMacros()] as $list) { |
|
2678 | + foreach ($list as $callback) { |
|
2679 | + try { |
|
2680 | + return $this->executeCallable($callback, $method, ...$parameters); |
|
2681 | + } catch (BadMethodCallException $exception) { |
|
2682 | + continue; |
|
2683 | + } |
|
2684 | + } |
|
2685 | + } |
|
2686 | + |
|
2687 | + if ($this->localStrictModeEnabled ?? static::isStrictModeEnabled()) { |
|
2688 | + throw new UnknownMethodException($method); |
|
2689 | + } |
|
2690 | + |
|
2691 | + return null; |
|
2692 | + } |
|
2693 | + |
|
2694 | + return $this->executeCallable($macro, ...$parameters); |
|
2695 | + }); |
|
2696 | + } |
|
2697 | 2697 | } |
@@ -26,214 +26,214 @@ |
||
26 | 26 | */ |
27 | 27 | trait Rounding |
28 | 28 | { |
29 | - use IntervalRounding; |
|
30 | - |
|
31 | - /** |
|
32 | - * Round the current instance at the given unit with given precision if specified and the given function. |
|
33 | - * |
|
34 | - * @param string $unit |
|
35 | - * @param float|int $precision |
|
36 | - * @param string $function |
|
37 | - * |
|
38 | - * @return CarbonInterface |
|
39 | - */ |
|
40 | - public function roundUnit($unit, $precision = 1, $function = 'round') |
|
41 | - { |
|
42 | - $metaUnits = [ |
|
43 | - // @call roundUnit |
|
44 | - 'millennium' => [static::YEARS_PER_MILLENNIUM, 'year'], |
|
45 | - // @call roundUnit |
|
46 | - 'century' => [static::YEARS_PER_CENTURY, 'year'], |
|
47 | - // @call roundUnit |
|
48 | - 'decade' => [static::YEARS_PER_DECADE, 'year'], |
|
49 | - // @call roundUnit |
|
50 | - 'quarter' => [static::MONTHS_PER_QUARTER, 'month'], |
|
51 | - // @call roundUnit |
|
52 | - 'millisecond' => [1000, 'microsecond'], |
|
53 | - ]; |
|
54 | - $normalizedUnit = static::singularUnit($unit); |
|
55 | - $ranges = array_merge(static::getRangesByUnit($this->daysInMonth), [ |
|
56 | - // @call roundUnit |
|
57 | - 'microsecond' => [0, 999999], |
|
58 | - ]); |
|
59 | - $factor = 1; |
|
60 | - $initialMonth = $this->month; |
|
61 | - |
|
62 | - if ($normalizedUnit === 'week') { |
|
63 | - $normalizedUnit = 'day'; |
|
64 | - $precision *= static::DAYS_PER_WEEK; |
|
65 | - } |
|
66 | - |
|
67 | - if (isset($metaUnits[$normalizedUnit])) { |
|
68 | - [$factor, $normalizedUnit] = $metaUnits[$normalizedUnit]; |
|
69 | - } |
|
70 | - |
|
71 | - $precision *= $factor; |
|
72 | - |
|
73 | - if (!isset($ranges[$normalizedUnit])) { |
|
74 | - throw new UnknownUnitException($unit); |
|
75 | - } |
|
76 | - |
|
77 | - $found = false; |
|
78 | - $fraction = 0; |
|
79 | - $arguments = null; |
|
80 | - $factor = $this->year < 0 ? -1 : 1; |
|
81 | - $changes = []; |
|
82 | - |
|
83 | - foreach ($ranges as $unit => [$minimum, $maximum]) { |
|
84 | - if ($normalizedUnit === $unit) { |
|
85 | - $arguments = [$this->$unit, $minimum]; |
|
86 | - $fraction = $precision - floor($precision); |
|
87 | - $found = true; |
|
88 | - |
|
89 | - continue; |
|
90 | - } |
|
91 | - |
|
92 | - if ($found) { |
|
93 | - $delta = $maximum + 1 - $minimum; |
|
94 | - $factor /= $delta; |
|
95 | - $fraction *= $delta; |
|
96 | - $arguments[0] += ($this->$unit - $minimum) * $factor; |
|
97 | - $changes[$unit] = round( |
|
98 | - $minimum + ($fraction ? $fraction * $function(($this->$unit - $minimum) / $fraction) : 0) |
|
99 | - ); |
|
100 | - |
|
101 | - // Cannot use modulo as it lose double precision |
|
102 | - while ($changes[$unit] >= $delta) { |
|
103 | - $changes[$unit] -= $delta; |
|
104 | - } |
|
105 | - |
|
106 | - $fraction -= floor($fraction); |
|
107 | - } |
|
108 | - } |
|
109 | - |
|
110 | - [$value, $minimum] = $arguments; |
|
111 | - $normalizedValue = floor($function(($value - $minimum) / $precision) * $precision + $minimum); |
|
112 | - |
|
113 | - /** @var CarbonInterface $result */ |
|
114 | - $result = $this->$normalizedUnit($normalizedValue); |
|
115 | - |
|
116 | - foreach ($changes as $unit => $value) { |
|
117 | - $result = $result->$unit($value); |
|
118 | - } |
|
119 | - |
|
120 | - return $normalizedUnit === 'month' && $precision <= 1 && abs($result->month - $initialMonth) === 2 |
|
121 | - // Re-run the change in case an overflow occurred |
|
122 | - ? $result->$normalizedUnit($normalizedValue) |
|
123 | - : $result; |
|
124 | - } |
|
125 | - |
|
126 | - /** |
|
127 | - * Truncate the current instance at the given unit with given precision if specified. |
|
128 | - * |
|
129 | - * @param string $unit |
|
130 | - * @param float|int $precision |
|
131 | - * |
|
132 | - * @return CarbonInterface |
|
133 | - */ |
|
134 | - public function floorUnit($unit, $precision = 1) |
|
135 | - { |
|
136 | - return $this->roundUnit($unit, $precision, 'floor'); |
|
137 | - } |
|
138 | - |
|
139 | - /** |
|
140 | - * Ceil the current instance at the given unit with given precision if specified. |
|
141 | - * |
|
142 | - * @param string $unit |
|
143 | - * @param float|int $precision |
|
144 | - * |
|
145 | - * @return CarbonInterface |
|
146 | - */ |
|
147 | - public function ceilUnit($unit, $precision = 1) |
|
148 | - { |
|
149 | - return $this->roundUnit($unit, $precision, 'ceil'); |
|
150 | - } |
|
151 | - |
|
152 | - /** |
|
153 | - * Round the current instance second with given precision if specified. |
|
154 | - * |
|
155 | - * @param float|int|string|\DateInterval|null $precision |
|
156 | - * @param string $function |
|
157 | - * |
|
158 | - * @return CarbonInterface |
|
159 | - */ |
|
160 | - public function round($precision = 1, $function = 'round') |
|
161 | - { |
|
162 | - return $this->roundWith($precision, $function); |
|
163 | - } |
|
164 | - |
|
165 | - /** |
|
166 | - * Round the current instance second with given precision if specified. |
|
167 | - * |
|
168 | - * @param float|int|string|\DateInterval|null $precision |
|
169 | - * |
|
170 | - * @return CarbonInterface |
|
171 | - */ |
|
172 | - public function floor($precision = 1) |
|
173 | - { |
|
174 | - return $this->round($precision, 'floor'); |
|
175 | - } |
|
176 | - |
|
177 | - /** |
|
178 | - * Ceil the current instance second with given precision if specified. |
|
179 | - * |
|
180 | - * @param float|int|string|\DateInterval|null $precision |
|
181 | - * |
|
182 | - * @return CarbonInterface |
|
183 | - */ |
|
184 | - public function ceil($precision = 1) |
|
185 | - { |
|
186 | - return $this->round($precision, 'ceil'); |
|
187 | - } |
|
188 | - |
|
189 | - /** |
|
190 | - * Round the current instance week. |
|
191 | - * |
|
192 | - * @param int $weekStartsAt optional start allow you to specify the day of week to use to start the week |
|
193 | - * |
|
194 | - * @return CarbonInterface |
|
195 | - */ |
|
196 | - public function roundWeek($weekStartsAt = null) |
|
197 | - { |
|
198 | - return $this->closest( |
|
199 | - $this->avoidMutation()->floorWeek($weekStartsAt), |
|
200 | - $this->avoidMutation()->ceilWeek($weekStartsAt) |
|
201 | - ); |
|
202 | - } |
|
203 | - |
|
204 | - /** |
|
205 | - * Truncate the current instance week. |
|
206 | - * |
|
207 | - * @param int $weekStartsAt optional start allow you to specify the day of week to use to start the week |
|
208 | - * |
|
209 | - * @return CarbonInterface |
|
210 | - */ |
|
211 | - public function floorWeek($weekStartsAt = null) |
|
212 | - { |
|
213 | - return $this->startOfWeek($weekStartsAt); |
|
214 | - } |
|
215 | - |
|
216 | - /** |
|
217 | - * Ceil the current instance week. |
|
218 | - * |
|
219 | - * @param int $weekStartsAt optional start allow you to specify the day of week to use to start the week |
|
220 | - * |
|
221 | - * @return CarbonInterface |
|
222 | - */ |
|
223 | - public function ceilWeek($weekStartsAt = null) |
|
224 | - { |
|
225 | - if ($this->isMutable()) { |
|
226 | - $startOfWeek = $this->avoidMutation()->startOfWeek($weekStartsAt); |
|
227 | - |
|
228 | - return $startOfWeek != $this ? |
|
229 | - $this->startOfWeek($weekStartsAt)->addWeek() : |
|
230 | - $this; |
|
231 | - } |
|
232 | - |
|
233 | - $startOfWeek = $this->startOfWeek($weekStartsAt); |
|
234 | - |
|
235 | - return $startOfWeek != $this ? |
|
236 | - $startOfWeek->addWeek() : |
|
237 | - $this->avoidMutation(); |
|
238 | - } |
|
29 | + use IntervalRounding; |
|
30 | + |
|
31 | + /** |
|
32 | + * Round the current instance at the given unit with given precision if specified and the given function. |
|
33 | + * |
|
34 | + * @param string $unit |
|
35 | + * @param float|int $precision |
|
36 | + * @param string $function |
|
37 | + * |
|
38 | + * @return CarbonInterface |
|
39 | + */ |
|
40 | + public function roundUnit($unit, $precision = 1, $function = 'round') |
|
41 | + { |
|
42 | + $metaUnits = [ |
|
43 | + // @call roundUnit |
|
44 | + 'millennium' => [static::YEARS_PER_MILLENNIUM, 'year'], |
|
45 | + // @call roundUnit |
|
46 | + 'century' => [static::YEARS_PER_CENTURY, 'year'], |
|
47 | + // @call roundUnit |
|
48 | + 'decade' => [static::YEARS_PER_DECADE, 'year'], |
|
49 | + // @call roundUnit |
|
50 | + 'quarter' => [static::MONTHS_PER_QUARTER, 'month'], |
|
51 | + // @call roundUnit |
|
52 | + 'millisecond' => [1000, 'microsecond'], |
|
53 | + ]; |
|
54 | + $normalizedUnit = static::singularUnit($unit); |
|
55 | + $ranges = array_merge(static::getRangesByUnit($this->daysInMonth), [ |
|
56 | + // @call roundUnit |
|
57 | + 'microsecond' => [0, 999999], |
|
58 | + ]); |
|
59 | + $factor = 1; |
|
60 | + $initialMonth = $this->month; |
|
61 | + |
|
62 | + if ($normalizedUnit === 'week') { |
|
63 | + $normalizedUnit = 'day'; |
|
64 | + $precision *= static::DAYS_PER_WEEK; |
|
65 | + } |
|
66 | + |
|
67 | + if (isset($metaUnits[$normalizedUnit])) { |
|
68 | + [$factor, $normalizedUnit] = $metaUnits[$normalizedUnit]; |
|
69 | + } |
|
70 | + |
|
71 | + $precision *= $factor; |
|
72 | + |
|
73 | + if (!isset($ranges[$normalizedUnit])) { |
|
74 | + throw new UnknownUnitException($unit); |
|
75 | + } |
|
76 | + |
|
77 | + $found = false; |
|
78 | + $fraction = 0; |
|
79 | + $arguments = null; |
|
80 | + $factor = $this->year < 0 ? -1 : 1; |
|
81 | + $changes = []; |
|
82 | + |
|
83 | + foreach ($ranges as $unit => [$minimum, $maximum]) { |
|
84 | + if ($normalizedUnit === $unit) { |
|
85 | + $arguments = [$this->$unit, $minimum]; |
|
86 | + $fraction = $precision - floor($precision); |
|
87 | + $found = true; |
|
88 | + |
|
89 | + continue; |
|
90 | + } |
|
91 | + |
|
92 | + if ($found) { |
|
93 | + $delta = $maximum + 1 - $minimum; |
|
94 | + $factor /= $delta; |
|
95 | + $fraction *= $delta; |
|
96 | + $arguments[0] += ($this->$unit - $minimum) * $factor; |
|
97 | + $changes[$unit] = round( |
|
98 | + $minimum + ($fraction ? $fraction * $function(($this->$unit - $minimum) / $fraction) : 0) |
|
99 | + ); |
|
100 | + |
|
101 | + // Cannot use modulo as it lose double precision |
|
102 | + while ($changes[$unit] >= $delta) { |
|
103 | + $changes[$unit] -= $delta; |
|
104 | + } |
|
105 | + |
|
106 | + $fraction -= floor($fraction); |
|
107 | + } |
|
108 | + } |
|
109 | + |
|
110 | + [$value, $minimum] = $arguments; |
|
111 | + $normalizedValue = floor($function(($value - $minimum) / $precision) * $precision + $minimum); |
|
112 | + |
|
113 | + /** @var CarbonInterface $result */ |
|
114 | + $result = $this->$normalizedUnit($normalizedValue); |
|
115 | + |
|
116 | + foreach ($changes as $unit => $value) { |
|
117 | + $result = $result->$unit($value); |
|
118 | + } |
|
119 | + |
|
120 | + return $normalizedUnit === 'month' && $precision <= 1 && abs($result->month - $initialMonth) === 2 |
|
121 | + // Re-run the change in case an overflow occurred |
|
122 | + ? $result->$normalizedUnit($normalizedValue) |
|
123 | + : $result; |
|
124 | + } |
|
125 | + |
|
126 | + /** |
|
127 | + * Truncate the current instance at the given unit with given precision if specified. |
|
128 | + * |
|
129 | + * @param string $unit |
|
130 | + * @param float|int $precision |
|
131 | + * |
|
132 | + * @return CarbonInterface |
|
133 | + */ |
|
134 | + public function floorUnit($unit, $precision = 1) |
|
135 | + { |
|
136 | + return $this->roundUnit($unit, $precision, 'floor'); |
|
137 | + } |
|
138 | + |
|
139 | + /** |
|
140 | + * Ceil the current instance at the given unit with given precision if specified. |
|
141 | + * |
|
142 | + * @param string $unit |
|
143 | + * @param float|int $precision |
|
144 | + * |
|
145 | + * @return CarbonInterface |
|
146 | + */ |
|
147 | + public function ceilUnit($unit, $precision = 1) |
|
148 | + { |
|
149 | + return $this->roundUnit($unit, $precision, 'ceil'); |
|
150 | + } |
|
151 | + |
|
152 | + /** |
|
153 | + * Round the current instance second with given precision if specified. |
|
154 | + * |
|
155 | + * @param float|int|string|\DateInterval|null $precision |
|
156 | + * @param string $function |
|
157 | + * |
|
158 | + * @return CarbonInterface |
|
159 | + */ |
|
160 | + public function round($precision = 1, $function = 'round') |
|
161 | + { |
|
162 | + return $this->roundWith($precision, $function); |
|
163 | + } |
|
164 | + |
|
165 | + /** |
|
166 | + * Round the current instance second with given precision if specified. |
|
167 | + * |
|
168 | + * @param float|int|string|\DateInterval|null $precision |
|
169 | + * |
|
170 | + * @return CarbonInterface |
|
171 | + */ |
|
172 | + public function floor($precision = 1) |
|
173 | + { |
|
174 | + return $this->round($precision, 'floor'); |
|
175 | + } |
|
176 | + |
|
177 | + /** |
|
178 | + * Ceil the current instance second with given precision if specified. |
|
179 | + * |
|
180 | + * @param float|int|string|\DateInterval|null $precision |
|
181 | + * |
|
182 | + * @return CarbonInterface |
|
183 | + */ |
|
184 | + public function ceil($precision = 1) |
|
185 | + { |
|
186 | + return $this->round($precision, 'ceil'); |
|
187 | + } |
|
188 | + |
|
189 | + /** |
|
190 | + * Round the current instance week. |
|
191 | + * |
|
192 | + * @param int $weekStartsAt optional start allow you to specify the day of week to use to start the week |
|
193 | + * |
|
194 | + * @return CarbonInterface |
|
195 | + */ |
|
196 | + public function roundWeek($weekStartsAt = null) |
|
197 | + { |
|
198 | + return $this->closest( |
|
199 | + $this->avoidMutation()->floorWeek($weekStartsAt), |
|
200 | + $this->avoidMutation()->ceilWeek($weekStartsAt) |
|
201 | + ); |
|
202 | + } |
|
203 | + |
|
204 | + /** |
|
205 | + * Truncate the current instance week. |
|
206 | + * |
|
207 | + * @param int $weekStartsAt optional start allow you to specify the day of week to use to start the week |
|
208 | + * |
|
209 | + * @return CarbonInterface |
|
210 | + */ |
|
211 | + public function floorWeek($weekStartsAt = null) |
|
212 | + { |
|
213 | + return $this->startOfWeek($weekStartsAt); |
|
214 | + } |
|
215 | + |
|
216 | + /** |
|
217 | + * Ceil the current instance week. |
|
218 | + * |
|
219 | + * @param int $weekStartsAt optional start allow you to specify the day of week to use to start the week |
|
220 | + * |
|
221 | + * @return CarbonInterface |
|
222 | + */ |
|
223 | + public function ceilWeek($weekStartsAt = null) |
|
224 | + { |
|
225 | + if ($this->isMutable()) { |
|
226 | + $startOfWeek = $this->avoidMutation()->startOfWeek($weekStartsAt); |
|
227 | + |
|
228 | + return $startOfWeek != $this ? |
|
229 | + $this->startOfWeek($weekStartsAt)->addWeek() : |
|
230 | + $this; |
|
231 | + } |
|
232 | + |
|
233 | + $startOfWeek = $this->startOfWeek($weekStartsAt); |
|
234 | + |
|
235 | + return $startOfWeek != $this ? |
|
236 | + $startOfWeek->addWeek() : |
|
237 | + $this->avoidMutation(); |
|
238 | + } |
|
239 | 239 | } |
@@ -226,14 +226,12 @@ |
||
226 | 226 | $startOfWeek = $this->avoidMutation()->startOfWeek($weekStartsAt); |
227 | 227 | |
228 | 228 | return $startOfWeek != $this ? |
229 | - $this->startOfWeek($weekStartsAt)->addWeek() : |
|
230 | - $this; |
|
229 | + $this->startOfWeek($weekStartsAt)->addWeek() : $this; |
|
231 | 230 | } |
232 | 231 | |
233 | 232 | $startOfWeek = $this->startOfWeek($weekStartsAt); |
234 | 233 | |
235 | 234 | return $startOfWeek != $this ? |
236 | - $startOfWeek->addWeek() : |
|
237 | - $this->avoidMutation(); |
|
235 | + $startOfWeek->addWeek() : $this->avoidMutation(); |
|
238 | 236 | } |
239 | 237 | } |
@@ -21,23 +21,23 @@ |
||
21 | 21 | */ |
22 | 22 | trait Cast |
23 | 23 | { |
24 | - /** |
|
25 | - * Cast the current instance into the given class. |
|
26 | - * |
|
27 | - * @param string $className The $className::instance() method will be called to cast the current object. |
|
28 | - * |
|
29 | - * @return DateTimeInterface |
|
30 | - */ |
|
31 | - public function cast(string $className) |
|
32 | - { |
|
33 | - if (!method_exists($className, 'instance')) { |
|
34 | - if (is_a($className, DateTimeInterface::class, true)) { |
|
35 | - return new $className($this->rawFormat('Y-m-d H:i:s.u'), $this->getTimezone()); |
|
36 | - } |
|
24 | + /** |
|
25 | + * Cast the current instance into the given class. |
|
26 | + * |
|
27 | + * @param string $className The $className::instance() method will be called to cast the current object. |
|
28 | + * |
|
29 | + * @return DateTimeInterface |
|
30 | + */ |
|
31 | + public function cast(string $className) |
|
32 | + { |
|
33 | + if (!method_exists($className, 'instance')) { |
|
34 | + if (is_a($className, DateTimeInterface::class, true)) { |
|
35 | + return new $className($this->rawFormat('Y-m-d H:i:s.u'), $this->getTimezone()); |
|
36 | + } |
|
37 | 37 | |
38 | - throw new InvalidCastException("$className has not the instance() method needed to cast the date."); |
|
39 | - } |
|
38 | + throw new InvalidCastException("$className has not the instance() method needed to cast the date."); |
|
39 | + } |
|
40 | 40 | |
41 | - return $className::instance($this); |
|
42 | - } |
|
41 | + return $className::instance($this); |
|
42 | + } |
|
43 | 43 | } |
@@ -20,74 +20,74 @@ |
||
20 | 20 | |
21 | 21 | trait IntervalStep |
22 | 22 | { |
23 | - /** |
|
24 | - * Step to apply instead of a fixed interval to get the new date. |
|
25 | - * |
|
26 | - * @var Closure|null |
|
27 | - */ |
|
28 | - protected $step; |
|
23 | + /** |
|
24 | + * Step to apply instead of a fixed interval to get the new date. |
|
25 | + * |
|
26 | + * @var Closure|null |
|
27 | + */ |
|
28 | + protected $step; |
|
29 | 29 | |
30 | - /** |
|
31 | - * Get the dynamic step in use. |
|
32 | - * |
|
33 | - * @return Closure |
|
34 | - */ |
|
35 | - public function getStep(): ?Closure |
|
36 | - { |
|
37 | - return $this->step; |
|
38 | - } |
|
30 | + /** |
|
31 | + * Get the dynamic step in use. |
|
32 | + * |
|
33 | + * @return Closure |
|
34 | + */ |
|
35 | + public function getStep(): ?Closure |
|
36 | + { |
|
37 | + return $this->step; |
|
38 | + } |
|
39 | 39 | |
40 | - /** |
|
41 | - * Set a step to apply instead of a fixed interval to get the new date. |
|
42 | - * |
|
43 | - * Or pass null to switch to fixed interval. |
|
44 | - * |
|
45 | - * @param Closure|null $step |
|
46 | - */ |
|
47 | - public function setStep(?Closure $step): void |
|
48 | - { |
|
49 | - $this->step = $step; |
|
50 | - } |
|
40 | + /** |
|
41 | + * Set a step to apply instead of a fixed interval to get the new date. |
|
42 | + * |
|
43 | + * Or pass null to switch to fixed interval. |
|
44 | + * |
|
45 | + * @param Closure|null $step |
|
46 | + */ |
|
47 | + public function setStep(?Closure $step): void |
|
48 | + { |
|
49 | + $this->step = $step; |
|
50 | + } |
|
51 | 51 | |
52 | - /** |
|
53 | - * Take a date and apply either the step if set, or the current interval else. |
|
54 | - * |
|
55 | - * The interval/step is applied negatively (typically subtraction instead of addition) if $negated is true. |
|
56 | - * |
|
57 | - * @param DateTimeInterface $dateTime |
|
58 | - * @param bool $negated |
|
59 | - * |
|
60 | - * @return CarbonInterface |
|
61 | - */ |
|
62 | - public function convertDate(DateTimeInterface $dateTime, bool $negated = false): CarbonInterface |
|
63 | - { |
|
64 | - /** @var CarbonInterface $carbonDate */ |
|
65 | - $carbonDate = $dateTime instanceof CarbonInterface ? $dateTime : $this->resolveCarbon($dateTime); |
|
52 | + /** |
|
53 | + * Take a date and apply either the step if set, or the current interval else. |
|
54 | + * |
|
55 | + * The interval/step is applied negatively (typically subtraction instead of addition) if $negated is true. |
|
56 | + * |
|
57 | + * @param DateTimeInterface $dateTime |
|
58 | + * @param bool $negated |
|
59 | + * |
|
60 | + * @return CarbonInterface |
|
61 | + */ |
|
62 | + public function convertDate(DateTimeInterface $dateTime, bool $negated = false): CarbonInterface |
|
63 | + { |
|
64 | + /** @var CarbonInterface $carbonDate */ |
|
65 | + $carbonDate = $dateTime instanceof CarbonInterface ? $dateTime : $this->resolveCarbon($dateTime); |
|
66 | 66 | |
67 | - if ($this->step) { |
|
68 | - return $carbonDate->setDateTimeFrom(($this->step)($carbonDate->avoidMutation(), $negated)); |
|
69 | - } |
|
67 | + if ($this->step) { |
|
68 | + return $carbonDate->setDateTimeFrom(($this->step)($carbonDate->avoidMutation(), $negated)); |
|
69 | + } |
|
70 | 70 | |
71 | - if ($negated) { |
|
72 | - return $carbonDate->rawSub($this); |
|
73 | - } |
|
71 | + if ($negated) { |
|
72 | + return $carbonDate->rawSub($this); |
|
73 | + } |
|
74 | 74 | |
75 | - return $carbonDate->rawAdd($this); |
|
76 | - } |
|
75 | + return $carbonDate->rawAdd($this); |
|
76 | + } |
|
77 | 77 | |
78 | - /** |
|
79 | - * Convert DateTimeImmutable instance to CarbonImmutable instance and DateTime instance to Carbon instance. |
|
80 | - * |
|
81 | - * @param DateTimeInterface $dateTime |
|
82 | - * |
|
83 | - * @return Carbon|CarbonImmutable |
|
84 | - */ |
|
85 | - private function resolveCarbon(DateTimeInterface $dateTime) |
|
86 | - { |
|
87 | - if ($dateTime instanceof DateTimeImmutable) { |
|
88 | - return CarbonImmutable::instance($dateTime); |
|
89 | - } |
|
78 | + /** |
|
79 | + * Convert DateTimeImmutable instance to CarbonImmutable instance and DateTime instance to Carbon instance. |
|
80 | + * |
|
81 | + * @param DateTimeInterface $dateTime |
|
82 | + * |
|
83 | + * @return Carbon|CarbonImmutable |
|
84 | + */ |
|
85 | + private function resolveCarbon(DateTimeInterface $dateTime) |
|
86 | + { |
|
87 | + if ($dateTime instanceof DateTimeImmutable) { |
|
88 | + return CarbonImmutable::instance($dateTime); |
|
89 | + } |
|
90 | 90 | |
91 | - return Carbon::instance($dateTime); |
|
92 | - } |
|
91 | + return Carbon::instance($dateTime); |
|
92 | + } |
|
93 | 93 | } |