Completed
Branch develop (eb876f)
by
unknown
21:14
created
php-imap/vendor/nesbot/carbon/src/Carbon/Doctrine/CarbonImmutableType.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -15,23 +15,23 @@
 block discarded – undo
15 15
 
16 16
 class CarbonImmutableType extends DateTimeImmutableType implements CarbonDoctrineType
17 17
 {
18
-    /**
19
-     * {@inheritdoc}
20
-     *
21
-     * @return string
22
-     */
23
-    public function getName()
24
-    {
25
-        return 'carbon_immutable';
26
-    }
18
+	/**
19
+	 * {@inheritdoc}
20
+	 *
21
+	 * @return string
22
+	 */
23
+	public function getName()
24
+	{
25
+		return 'carbon_immutable';
26
+	}
27 27
 
28
-    /**
29
-     * {@inheritdoc}
30
-     *
31
-     * @return bool
32
-     */
33
-    public function requiresSQLCommentHint(AbstractPlatform $platform)
34
-    {
35
-        return true;
36
-    }
28
+	/**
29
+	 * {@inheritdoc}
30
+	 *
31
+	 * @return bool
32
+	 */
33
+	public function requiresSQLCommentHint(AbstractPlatform $platform)
34
+	{
35
+		return true;
36
+	}
37 37
 }
Please login to merge, or discard this patch.
includes/webklex/php-imap/vendor/nesbot/carbon/src/Carbon/Factory.php 2 patches
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -241,86 +241,86 @@
 block discarded – undo
241 241
  */
242 242
 class Factory
243 243
 {
244
-    protected $className = Carbon::class;
244
+	protected $className = Carbon::class;
245 245
 
246
-    protected $settings = [];
246
+	protected $settings = [];
247 247
 
248
-    public function __construct(array $settings = [], ?string $className = null)
249
-    {
250
-        if ($className) {
251
-            $this->className = $className;
252
-        }
248
+	public function __construct(array $settings = [], ?string $className = null)
249
+	{
250
+		if ($className) {
251
+			$this->className = $className;
252
+		}
253 253
 
254
-        $this->settings = $settings;
255
-    }
254
+		$this->settings = $settings;
255
+	}
256 256
 
257
-    public function getClassName()
258
-    {
259
-        return $this->className;
260
-    }
257
+	public function getClassName()
258
+	{
259
+		return $this->className;
260
+	}
261 261
 
262
-    public function setClassName(string $className)
263
-    {
264
-        $this->className = $className;
262
+	public function setClassName(string $className)
263
+	{
264
+		$this->className = $className;
265 265
 
266
-        return $this;
267
-    }
266
+		return $this;
267
+	}
268 268
 
269
-    public function className(string $className = null)
270
-    {
271
-        return $className === null ? $this->getClassName() : $this->setClassName($className);
272
-    }
269
+	public function className(string $className = null)
270
+	{
271
+		return $className === null ? $this->getClassName() : $this->setClassName($className);
272
+	}
273 273
 
274
-    public function getSettings()
275
-    {
276
-        return $this->settings;
277
-    }
274
+	public function getSettings()
275
+	{
276
+		return $this->settings;
277
+	}
278 278
 
279
-    public function setSettings(array $settings)
280
-    {
281
-        $this->settings = $settings;
279
+	public function setSettings(array $settings)
280
+	{
281
+		$this->settings = $settings;
282 282
 
283
-        return $this;
284
-    }
283
+		return $this;
284
+	}
285 285
 
286
-    public function settings(array $settings = null)
287
-    {
288
-        return $settings === null ? $this->getSettings() : $this->setSettings($settings);
289
-    }
286
+	public function settings(array $settings = null)
287
+	{
288
+		return $settings === null ? $this->getSettings() : $this->setSettings($settings);
289
+	}
290 290
 
291
-    public function mergeSettings(array $settings)
292
-    {
293
-        $this->settings = array_merge($this->settings, $settings);
291
+	public function mergeSettings(array $settings)
292
+	{
293
+		$this->settings = array_merge($this->settings, $settings);
294 294
 
295
-        return $this;
296
-    }
295
+		return $this;
296
+	}
297 297
 
298
-    public function __call($name, $arguments)
299
-    {
300
-        $method = new ReflectionMethod($this->className, $name);
301
-        $settings = $this->settings;
298
+	public function __call($name, $arguments)
299
+	{
300
+		$method = new ReflectionMethod($this->className, $name);
301
+		$settings = $this->settings;
302 302
 
303
-        if ($settings && isset($settings['timezone'])) {
304
-            $tzParameters = array_filter($method->getParameters(), function ($parameter) {
305
-                return \in_array($parameter->getName(), ['tz', 'timezone'], true);
306
-            });
303
+		if ($settings && isset($settings['timezone'])) {
304
+			$tzParameters = array_filter($method->getParameters(), function ($parameter) {
305
+				return \in_array($parameter->getName(), ['tz', 'timezone'], true);
306
+			});
307 307
 
308
-            if (isset($arguments[0]) && \in_array($name, ['instance', 'make', 'create', 'parse'], true)) {
309
-                if ($arguments[0] instanceof DateTimeInterface) {
310
-                    $settings['innerTimezone'] = $settings['timezone'];
311
-                } elseif (\is_string($arguments[0]) && date_parse($arguments[0])['is_localtime']) {
312
-                    unset($settings['timezone'], $settings['innerTimezone']);
313
-                }
314
-            } elseif (\count($tzParameters)) {
315
-                array_splice($arguments, key($tzParameters), 0, [$settings['timezone']]);
316
-                unset($settings['timezone']);
317
-            }
318
-        }
308
+			if (isset($arguments[0]) && \in_array($name, ['instance', 'make', 'create', 'parse'], true)) {
309
+				if ($arguments[0] instanceof DateTimeInterface) {
310
+					$settings['innerTimezone'] = $settings['timezone'];
311
+				} elseif (\is_string($arguments[0]) && date_parse($arguments[0])['is_localtime']) {
312
+					unset($settings['timezone'], $settings['innerTimezone']);
313
+				}
314
+			} elseif (\count($tzParameters)) {
315
+				array_splice($arguments, key($tzParameters), 0, [$settings['timezone']]);
316
+				unset($settings['timezone']);
317
+			}
318
+		}
319 319
 
320
-        $result = $this->className::$name(...$arguments);
320
+		$result = $this->className::$name(...$arguments);
321 321
 
322
-        return $result instanceof CarbonInterface && !empty($settings)
323
-            ? $result->settings($settings)
324
-            : $result;
325
-    }
322
+		return $result instanceof CarbonInterface && !empty($settings)
323
+			? $result->settings($settings)
324
+			: $result;
325
+	}
326 326
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -301,7 +301,7 @@
 block discarded – undo
301 301
         $settings = $this->settings;
302 302
 
303 303
         if ($settings && isset($settings['timezone'])) {
304
-            $tzParameters = array_filter($method->getParameters(), function ($parameter) {
304
+            $tzParameters = array_filter($method->getParameters(), function($parameter) {
305 305
                 return \in_array($parameter->getName(), ['tz', 'timezone'], true);
306 306
             });
307 307
 
Please login to merge, or discard this patch.
includes/webklex/php-imap/vendor/nesbot/carbon/src/Carbon/Cli/Invoker.php 1 patch
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -13,26 +13,26 @@
 block discarded – undo
13 13
 
14 14
 class Invoker
15 15
 {
16
-    public const CLI_CLASS_NAME = 'Carbon\\Cli';
16
+	public const CLI_CLASS_NAME = 'Carbon\\Cli';
17 17
 
18
-    protected function runWithCli(string $className, array $parameters): bool
19
-    {
20
-        $cli = new $className();
18
+	protected function runWithCli(string $className, array $parameters): bool
19
+	{
20
+		$cli = new $className();
21 21
 
22
-        return $cli(...$parameters);
23
-    }
22
+		return $cli(...$parameters);
23
+	}
24 24
 
25
-    public function __invoke(...$parameters): bool
26
-    {
27
-        if (class_exists(self::CLI_CLASS_NAME)) {
28
-            return $this->runWithCli(self::CLI_CLASS_NAME, $parameters);
29
-        }
25
+	public function __invoke(...$parameters): bool
26
+	{
27
+		if (class_exists(self::CLI_CLASS_NAME)) {
28
+			return $this->runWithCli(self::CLI_CLASS_NAME, $parameters);
29
+		}
30 30
 
31
-        $function = (($parameters[1] ?? '') === 'install' ? ($parameters[2] ?? null) : null) ?: 'shell_exec';
32
-        $function('composer require carbon-cli/carbon-cli --no-interaction');
31
+		$function = (($parameters[1] ?? '') === 'install' ? ($parameters[2] ?? null) : null) ?: 'shell_exec';
32
+		$function('composer require carbon-cli/carbon-cli --no-interaction');
33 33
 
34
-        echo 'Installation succeeded.';
34
+		echo 'Installation succeeded.';
35 35
 
36
-        return true;
37
-    }
36
+		return true;
37
+	}
38 38
 }
Please login to merge, or discard this patch.
php-imap/vendor/nesbot/carbon/src/Carbon/TranslatorStrongTypeInterface.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -18,5 +18,5 @@
 block discarded – undo
18 18
  */
19 19
 interface TranslatorStrongTypeInterface
20 20
 {
21
-    public function getFromCatalogue(MessageCatalogueInterface $catalogue, string $id, string $domain = 'messages');
21
+	public function getFromCatalogue(MessageCatalogueInterface $catalogue, string $id, string $domain = 'messages');
22 22
 }
Please login to merge, or discard this patch.
includes/webklex/php-imap/vendor/nesbot/carbon/src/Carbon/CarbonPeriod.php 3 patches
Indentation   +2470 added lines, -2470 removed lines patch added patch discarded remove patch
@@ -170,2474 +170,2474 @@
 block discarded – undo
170 170
  */
171 171
 class CarbonPeriod implements Iterator, Countable, JsonSerializable
172 172
 {
173
-    use IntervalRounding;
174
-    use Mixin {
175
-        Mixin::mixin as baseMixin;
176
-    }
177
-    use Options;
178
-
179
-    /**
180
-     * Built-in filter for limit by recurrences.
181
-     *
182
-     * @var callable
183
-     */
184
-    public const RECURRENCES_FILTER = [self::class, 'filterRecurrences'];
185
-
186
-    /**
187
-     * Built-in filter for limit to an end.
188
-     *
189
-     * @var callable
190
-     */
191
-    public const END_DATE_FILTER = [self::class, 'filterEndDate'];
192
-
193
-    /**
194
-     * Special value which can be returned by filters to end iteration. Also a filter.
195
-     *
196
-     * @var callable
197
-     */
198
-    public const END_ITERATION = [self::class, 'endIteration'];
199
-
200
-    /**
201
-     * Exclude start date from iteration.
202
-     *
203
-     * @var int
204
-     */
205
-    public const EXCLUDE_START_DATE = 1;
206
-
207
-    /**
208
-     * Exclude end date from iteration.
209
-     *
210
-     * @var int
211
-     */
212
-    public const EXCLUDE_END_DATE = 2;
213
-
214
-    /**
215
-     * Yield CarbonImmutable instances.
216
-     *
217
-     * @var int
218
-     */
219
-    public const IMMUTABLE = 4;
220
-
221
-    /**
222
-     * Number of maximum attempts before giving up on finding next valid date.
223
-     *
224
-     * @var int
225
-     */
226
-    public const NEXT_MAX_ATTEMPTS = 1000;
227
-
228
-    /**
229
-     * Number of maximum attempts before giving up on finding end date.
230
-     *
231
-     * @var int
232
-     */
233
-    public const END_MAX_ATTEMPTS = 10000;
234
-
235
-    /**
236
-     * The registered macros.
237
-     *
238
-     * @var array
239
-     */
240
-    protected static $macros = [];
241
-
242
-    /**
243
-     * Date class of iteration items.
244
-     *
245
-     * @var string
246
-     */
247
-    protected $dateClass = Carbon::class;
248
-
249
-    /**
250
-     * Underlying date interval instance. Always present, one day by default.
251
-     *
252
-     * @var CarbonInterval
253
-     */
254
-    protected $dateInterval;
255
-
256
-    /**
257
-     * Whether current date interval was set by default.
258
-     *
259
-     * @var bool
260
-     */
261
-    protected $isDefaultInterval;
262
-
263
-    /**
264
-     * The filters stack.
265
-     *
266
-     * @var array
267
-     */
268
-    protected $filters = [];
269
-
270
-    /**
271
-     * Period start date. Applied on rewind. Always present, now by default.
272
-     *
273
-     * @var CarbonInterface
274
-     */
275
-    protected $startDate;
276
-
277
-    /**
278
-     * Period end date. For inverted interval should be before the start date. Applied via a filter.
279
-     *
280
-     * @var CarbonInterface|null
281
-     */
282
-    protected $endDate;
283
-
284
-    /**
285
-     * Limit for number of recurrences. Applied via a filter.
286
-     *
287
-     * @var int|null
288
-     */
289
-    protected $recurrences;
290
-
291
-    /**
292
-     * Iteration options.
293
-     *
294
-     * @var int
295
-     */
296
-    protected $options;
297
-
298
-    /**
299
-     * Index of current date. Always sequential, even if some dates are skipped by filters.
300
-     * Equal to null only before the first iteration.
301
-     *
302
-     * @var int
303
-     */
304
-    protected $key;
305
-
306
-    /**
307
-     * Current date. May temporarily hold unaccepted value when looking for a next valid date.
308
-     * Equal to null only before the first iteration.
309
-     *
310
-     * @var CarbonInterface
311
-     */
312
-    protected $current;
313
-
314
-    /**
315
-     * Timezone of current date. Taken from the start date.
316
-     *
317
-     * @var \DateTimeZone|null
318
-     */
319
-    protected $timezone;
320
-
321
-    /**
322
-     * The cached validation result for current date.
323
-     *
324
-     * @var bool|string|null
325
-     */
326
-    protected $validationResult;
327
-
328
-    /**
329
-     * Timezone handler for settings() method.
330
-     *
331
-     * @var mixed
332
-     */
333
-    protected $tzName;
334
-
335
-    /**
336
-     * Make a CarbonPeriod instance from given variable if possible.
337
-     *
338
-     * @param mixed $var
339
-     *
340
-     * @return static|null
341
-     */
342
-    public static function make($var)
343
-    {
344
-        try {
345
-            return static::instance($var);
346
-        } catch (NotAPeriodException $e) {
347
-            return static::create($var);
348
-        }
349
-    }
350
-
351
-    /**
352
-     * Create a new instance from a DatePeriod or CarbonPeriod object.
353
-     *
354
-     * @param CarbonPeriod|DatePeriod $period
355
-     *
356
-     * @return static
357
-     */
358
-    public static function instance($period)
359
-    {
360
-        if ($period instanceof static) {
361
-            return $period->copy();
362
-        }
363
-
364
-        if ($period instanceof self) {
365
-            return new static(
366
-                $period->getStartDate(),
367
-                $period->getEndDate() ?: $period->getRecurrences(),
368
-                $period->getDateInterval(),
369
-                $period->getOptions()
370
-            );
371
-        }
372
-
373
-        if ($period instanceof DatePeriod) {
374
-            return new static(
375
-                $period->start,
376
-                $period->end ?: ($period->recurrences - 1),
377
-                $period->interval,
378
-                $period->include_start_date ? 0 : static::EXCLUDE_START_DATE
379
-            );
380
-        }
381
-
382
-        $class = static::class;
383
-        $type = \gettype($period);
384
-
385
-        throw new NotAPeriodException(
386
-            'Argument 1 passed to '.$class.'::'.__METHOD__.'() '.
387
-            'must be an instance of DatePeriod or '.$class.', '.
388
-            ($type === 'object' ? 'instance of '.\get_class($period) : $type).' given.'
389
-        );
390
-    }
391
-
392
-    /**
393
-     * Create a new instance.
394
-     *
395
-     * @return static
396
-     */
397
-    public static function create(...$params)
398
-    {
399
-        return static::createFromArray($params);
400
-    }
401
-
402
-    /**
403
-     * Create a new instance from an array of parameters.
404
-     *
405
-     * @param array $params
406
-     *
407
-     * @return static
408
-     */
409
-    public static function createFromArray(array $params)
410
-    {
411
-        return new static(...$params);
412
-    }
413
-
414
-    /**
415
-     * Create CarbonPeriod from ISO 8601 string.
416
-     *
417
-     * @param string   $iso
418
-     * @param int|null $options
419
-     *
420
-     * @return static
421
-     */
422
-    public static function createFromIso($iso, $options = null)
423
-    {
424
-        $params = static::parseIso8601($iso);
425
-
426
-        $instance = static::createFromArray($params);
427
-
428
-        if ($options !== null) {
429
-            $instance->setOptions($options);
430
-        }
431
-
432
-        return $instance;
433
-    }
434
-
435
-    /**
436
-     * Return whether given interval contains non zero value of any time unit.
437
-     *
438
-     * @param \DateInterval $interval
439
-     *
440
-     * @return bool
441
-     */
442
-    protected static function intervalHasTime(DateInterval $interval)
443
-    {
444
-        return $interval->h || $interval->i || $interval->s || $interval->f;
445
-    }
446
-
447
-    /**
448
-     * Return whether given variable is an ISO 8601 specification.
449
-     *
450
-     * Note: Check is very basic, as actual validation will be done later when parsing.
451
-     * We just want to ensure that variable is not any other type of a valid parameter.
452
-     *
453
-     * @param mixed $var
454
-     *
455
-     * @return bool
456
-     */
457
-    protected static function isIso8601($var)
458
-    {
459
-        if (!\is_string($var)) {
460
-            return false;
461
-        }
462
-
463
-        // Match slash but not within a timezone name.
464
-        $part = '[a-z]+(?:[_-][a-z]+)*';
465
-
466
-        preg_match("#\b$part/$part\b|(/)#i", $var, $match);
467
-
468
-        return isset($match[1]);
469
-    }
470
-
471
-    /**
472
-     * Parse given ISO 8601 string into an array of arguments.
473
-     *
474
-     * @SuppressWarnings(PHPMD.ElseExpression)
475
-     *
476
-     * @param string $iso
477
-     *
478
-     * @return array
479
-     */
480
-    protected static function parseIso8601($iso)
481
-    {
482
-        $result = [];
483
-
484
-        $interval = null;
485
-        $start = null;
486
-        $end = null;
487
-
488
-        foreach (explode('/', $iso) as $key => $part) {
489
-            if ($key === 0 && preg_match('/^R(\d*|INF)$/', $part, $match)) {
490
-                $parsed = \strlen($match[1]) ? (($match[1] !== 'INF') ? (int) $match[1] : INF) : null;
491
-            } elseif ($interval === null && $parsed = CarbonInterval::make($part)) {
492
-                $interval = $part;
493
-            } elseif ($start === null && $parsed = Carbon::make($part)) {
494
-                $start = $part;
495
-            } elseif ($end === null && $parsed = Carbon::make(static::addMissingParts($start ?? '', $part))) {
496
-                $end = $part;
497
-            } else {
498
-                throw new InvalidPeriodParameterException("Invalid ISO 8601 specification: $iso.");
499
-            }
500
-
501
-            $result[] = $parsed;
502
-        }
503
-
504
-        return $result;
505
-    }
506
-
507
-    /**
508
-     * Add missing parts of the target date from the soure date.
509
-     *
510
-     * @param string $source
511
-     * @param string $target
512
-     *
513
-     * @return string
514
-     */
515
-    protected static function addMissingParts($source, $target)
516
-    {
517
-        $pattern = '/'.preg_replace('/\d+/', '[0-9]+', preg_quote($target, '/')).'$/';
518
-
519
-        $result = preg_replace($pattern, $target, $source, 1, $count);
520
-
521
-        return $count ? $result : $target;
522
-    }
523
-
524
-    /**
525
-     * Register a custom macro.
526
-     *
527
-     * @example
528
-     * ```
529
-     * CarbonPeriod::macro('middle', function () {
530
-     *   return $this->getStartDate()->average($this->getEndDate());
531
-     * });
532
-     * echo CarbonPeriod::since('2011-05-12')->until('2011-06-03')->middle();
533
-     * ```
534
-     *
535
-     * @param string          $name
536
-     * @param object|callable $macro
537
-     *
538
-     * @return void
539
-     */
540
-    public static function macro($name, $macro)
541
-    {
542
-        static::$macros[$name] = $macro;
543
-    }
544
-
545
-    /**
546
-     * Register macros from a mixin object.
547
-     *
548
-     * @example
549
-     * ```
550
-     * CarbonPeriod::mixin(new class {
551
-     *   public function addDays() {
552
-     *     return function ($count = 1) {
553
-     *       return $this->setStartDate(
554
-     *         $this->getStartDate()->addDays($count)
555
-     *       )->setEndDate(
556
-     *         $this->getEndDate()->addDays($count)
557
-     *       );
558
-     *     };
559
-     *   }
560
-     *   public function subDays() {
561
-     *     return function ($count = 1) {
562
-     *       return $this->setStartDate(
563
-     *         $this->getStartDate()->subDays($count)
564
-     *       )->setEndDate(
565
-     *         $this->getEndDate()->subDays($count)
566
-     *       );
567
-     *     };
568
-     *   }
569
-     * });
570
-     * echo CarbonPeriod::create('2000-01-01', '2000-02-01')->addDays(5)->subDays(3);
571
-     * ```
572
-     *
573
-     * @param object|string $mixin
574
-     *
575
-     * @throws ReflectionException
576
-     *
577
-     * @return void
578
-     */
579
-    public static function mixin($mixin)
580
-    {
581
-        static::baseMixin($mixin);
582
-    }
583
-
584
-    /**
585
-     * Check if macro is registered.
586
-     *
587
-     * @param string $name
588
-     *
589
-     * @return bool
590
-     */
591
-    public static function hasMacro($name)
592
-    {
593
-        return isset(static::$macros[$name]);
594
-    }
595
-
596
-    /**
597
-     * Provide static proxy for instance aliases.
598
-     *
599
-     * @param string $method
600
-     * @param array  $parameters
601
-     *
602
-     * @return mixed
603
-     */
604
-    public static function __callStatic($method, $parameters)
605
-    {
606
-        $date = new static();
607
-
608
-        if (static::hasMacro($method)) {
609
-            return static::bindMacroContext(null, function () use (&$method, &$parameters, &$date) {
610
-                return $date->callMacro($method, $parameters);
611
-            });
612
-        }
613
-
614
-        return $date->$method(...$parameters);
615
-    }
616
-
617
-    /**
618
-     * CarbonPeriod constructor.
619
-     *
620
-     * @SuppressWarnings(PHPMD.ElseExpression)
621
-     *
622
-     * @throws InvalidArgumentException
623
-     */
624
-    public function __construct(...$arguments)
625
-    {
626
-        // Parse and assign arguments one by one. First argument may be an ISO 8601 spec,
627
-        // which will be first parsed into parts and then processed the same way.
628
-
629
-        $argumentsCount = \count($arguments);
630
-
631
-        if ($argumentsCount && static::isIso8601($iso = $arguments[0])) {
632
-            array_splice($arguments, 0, 1, static::parseIso8601($iso));
633
-        }
634
-
635
-        if ($argumentsCount === 1) {
636
-            if ($arguments[0] instanceof DatePeriod) {
637
-                $arguments = [
638
-                    $arguments[0]->start,
639
-                    $arguments[0]->end ?: ($arguments[0]->recurrences - 1),
640
-                    $arguments[0]->interval,
641
-                    $arguments[0]->include_start_date ? 0 : static::EXCLUDE_START_DATE,
642
-                ];
643
-            } elseif ($arguments[0] instanceof self) {
644
-                $arguments = [
645
-                    $arguments[0]->getStartDate(),
646
-                    $arguments[0]->getEndDate() ?: $arguments[0]->getRecurrences(),
647
-                    $arguments[0]->getDateInterval(),
648
-                    $arguments[0]->getOptions(),
649
-                ];
650
-            }
651
-        }
652
-
653
-        foreach ($arguments as $argument) {
654
-            $parsedDate = null;
655
-
656
-            if ($argument instanceof DateTimeZone) {
657
-                $this->setTimezone($argument);
658
-            } elseif ($this->dateInterval === null &&
659
-                (
660
-                    (\is_string($argument) && preg_match(
661
-                        '/^(-?\d(\d(?![\/-])|[^\d\/-]([\/-])?)*|P[T\d].*|(?:\h*\d+(?:\.\d+)?\h*[a-z]+)+)$/i',
662
-                        $argument
663
-                    )) ||
664
-                    $argument instanceof DateInterval ||
665
-                    $argument instanceof Closure
666
-                ) &&
667
-                $parsedInterval = @CarbonInterval::make($argument)
668
-            ) {
669
-                $this->setDateInterval($parsedInterval);
670
-            } elseif ($this->startDate === null && $parsedDate = $this->makeDateTime($argument)) {
671
-                $this->setStartDate($parsedDate);
672
-            } elseif ($this->endDate === null && ($parsedDate = $parsedDate ?? $this->makeDateTime($argument))) {
673
-                $this->setEndDate($parsedDate);
674
-            } elseif ($this->recurrences === null && $this->endDate === null && is_numeric($argument)) {
675
-                $this->setRecurrences($argument);
676
-            } elseif ($this->options === null && (\is_int($argument) || $argument === null)) {
677
-                $this->setOptions($argument);
678
-            } else {
679
-                throw new InvalidPeriodParameterException('Invalid constructor parameters.');
680
-            }
681
-        }
682
-
683
-        if ($this->startDate === null) {
684
-            $this->setStartDate(Carbon::now());
685
-        }
686
-
687
-        if ($this->dateInterval === null) {
688
-            $this->setDateInterval(CarbonInterval::day());
689
-
690
-            $this->isDefaultInterval = true;
691
-        }
692
-
693
-        if ($this->options === null) {
694
-            $this->setOptions(0);
695
-        }
696
-    }
697
-
698
-    /**
699
-     * Get a copy of the instance.
700
-     *
701
-     * @return static
702
-     */
703
-    public function copy()
704
-    {
705
-        return clone $this;
706
-    }
707
-
708
-    /**
709
-     * Get the getter for a property allowing both `DatePeriod` snakeCase and camelCase names.
710
-     *
711
-     * @param string $name
712
-     *
713
-     * @return callable|null
714
-     */
715
-    protected function getGetter(string $name)
716
-    {
717
-        switch (strtolower(preg_replace('/[A-Z]/', '_$0', $name))) {
718
-            case 'start':
719
-            case 'start_date':
720
-                return [$this, 'getStartDate'];
721
-            case 'end':
722
-            case 'end_date':
723
-                return [$this, 'getEndDate'];
724
-            case 'interval':
725
-            case 'date_interval':
726
-                return [$this, 'getDateInterval'];
727
-            case 'recurrences':
728
-                return [$this, 'getRecurrences'];
729
-            case 'include_start_date':
730
-                return [$this, 'isStartIncluded'];
731
-            case 'include_end_date':
732
-                return [$this, 'isEndIncluded'];
733
-            case 'current':
734
-                return [$this, 'current'];
735
-            default:
736
-                return null;
737
-        }
738
-    }
739
-
740
-    /**
741
-     * Get a property allowing both `DatePeriod` snakeCase and camelCase names.
742
-     *
743
-     * @param string $name
744
-     *
745
-     * @return bool|CarbonInterface|CarbonInterval|int|null
746
-     */
747
-    public function get(string $name)
748
-    {
749
-        $getter = $this->getGetter($name);
750
-
751
-        if ($getter) {
752
-            return $getter();
753
-        }
754
-
755
-        throw new UnknownGetterException($name);
756
-    }
757
-
758
-    /**
759
-     * Get a property allowing both `DatePeriod` snakeCase and camelCase names.
760
-     *
761
-     * @param string $name
762
-     *
763
-     * @return bool|CarbonInterface|CarbonInterval|int|null
764
-     */
765
-    public function __get(string $name)
766
-    {
767
-        return $this->get($name);
768
-    }
769
-
770
-    /**
771
-     * Check if an attribute exists on the object
772
-     *
773
-     * @param string $name
774
-     *
775
-     * @return bool
776
-     */
777
-    public function __isset(string $name): bool
778
-    {
779
-        return $this->getGetter($name) !== null;
780
-    }
781
-
782
-    /**
783
-     * @alias copy
784
-     *
785
-     * Get a copy of the instance.
786
-     *
787
-     * @return static
788
-     */
789
-    public function clone()
790
-    {
791
-        return clone $this;
792
-    }
793
-
794
-    /**
795
-     * Set the iteration item class.
796
-     *
797
-     * @param string $dateClass
798
-     *
799
-     * @return $this
800
-     */
801
-    public function setDateClass(string $dateClass)
802
-    {
803
-        if (!is_a($dateClass, CarbonInterface::class, true)) {
804
-            throw new NotACarbonClassException($dateClass);
805
-        }
806
-
807
-        $this->dateClass = $dateClass;
808
-
809
-        if (is_a($dateClass, Carbon::class, true)) {
810
-            $this->toggleOptions(static::IMMUTABLE, false);
811
-        } elseif (is_a($dateClass, CarbonImmutable::class, true)) {
812
-            $this->toggleOptions(static::IMMUTABLE, true);
813
-        }
814
-
815
-        return $this;
816
-    }
817
-
818
-    /**
819
-     * Returns iteration item date class.
820
-     *
821
-     * @return string
822
-     */
823
-    public function getDateClass(): string
824
-    {
825
-        return $this->dateClass;
826
-    }
827
-
828
-    /**
829
-     * Change the period date interval.
830
-     *
831
-     * @param DateInterval|string $interval
832
-     *
833
-     * @throws InvalidIntervalException
834
-     *
835
-     * @return $this
836
-     */
837
-    public function setDateInterval($interval)
838
-    {
839
-        if (!$interval = CarbonInterval::make($interval)) {
840
-            throw new InvalidIntervalException('Invalid interval.');
841
-        }
842
-
843
-        if ($interval->spec() === 'PT0S' && !$interval->f && !$interval->getStep()) {
844
-            throw new InvalidIntervalException('Empty interval is not accepted.');
845
-        }
846
-
847
-        $this->dateInterval = $interval;
848
-
849
-        $this->isDefaultInterval = false;
850
-
851
-        $this->handleChangedParameters();
852
-
853
-        return $this;
854
-    }
855
-
856
-    /**
857
-     * Invert the period date interval.
858
-     *
859
-     * @return $this
860
-     */
861
-    public function invertDateInterval()
862
-    {
863
-        $interval = $this->dateInterval->invert();
864
-
865
-        return $this->setDateInterval($interval);
866
-    }
867
-
868
-    /**
869
-     * Set start and end date.
870
-     *
871
-     * @param DateTime|DateTimeInterface|string      $start
872
-     * @param DateTime|DateTimeInterface|string|null $end
873
-     *
874
-     * @return $this
875
-     */
876
-    public function setDates($start, $end)
877
-    {
878
-        $this->setStartDate($start);
879
-        $this->setEndDate($end);
880
-
881
-        return $this;
882
-    }
883
-
884
-    /**
885
-     * Change the period options.
886
-     *
887
-     * @param int|null $options
888
-     *
889
-     * @throws InvalidArgumentException
890
-     *
891
-     * @return $this
892
-     */
893
-    public function setOptions($options)
894
-    {
895
-        if (!\is_int($options) && $options !== null) {
896
-            throw new InvalidPeriodParameterException('Invalid options.');
897
-        }
898
-
899
-        $this->options = $options ?: 0;
900
-
901
-        $this->handleChangedParameters();
902
-
903
-        return $this;
904
-    }
905
-
906
-    /**
907
-     * Get the period options.
908
-     *
909
-     * @return int
910
-     */
911
-    public function getOptions()
912
-    {
913
-        return $this->options;
914
-    }
915
-
916
-    /**
917
-     * Toggle given options on or off.
918
-     *
919
-     * @param int       $options
920
-     * @param bool|null $state
921
-     *
922
-     * @throws \InvalidArgumentException
923
-     *
924
-     * @return $this
925
-     */
926
-    public function toggleOptions($options, $state = null)
927
-    {
928
-        if ($state === null) {
929
-            $state = ($this->options & $options) !== $options;
930
-        }
931
-
932
-        return $this->setOptions(
933
-            $state ?
934
-            $this->options | $options :
935
-            $this->options & ~$options
936
-        );
937
-    }
938
-
939
-    /**
940
-     * Toggle EXCLUDE_START_DATE option.
941
-     *
942
-     * @param bool $state
943
-     *
944
-     * @return $this
945
-     */
946
-    public function excludeStartDate($state = true)
947
-    {
948
-        return $this->toggleOptions(static::EXCLUDE_START_DATE, $state);
949
-    }
950
-
951
-    /**
952
-     * Toggle EXCLUDE_END_DATE option.
953
-     *
954
-     * @param bool $state
955
-     *
956
-     * @return $this
957
-     */
958
-    public function excludeEndDate($state = true)
959
-    {
960
-        return $this->toggleOptions(static::EXCLUDE_END_DATE, $state);
961
-    }
962
-
963
-    /**
964
-     * Get the underlying date interval.
965
-     *
966
-     * @return CarbonInterval
967
-     */
968
-    public function getDateInterval()
969
-    {
970
-        return $this->dateInterval->copy();
971
-    }
972
-
973
-    /**
974
-     * Get start date of the period.
975
-     *
976
-     * @param string|null $rounding Optional rounding 'floor', 'ceil', 'round' using the period interval.
977
-     *
978
-     * @return CarbonInterface
979
-     */
980
-    public function getStartDate(string $rounding = null)
981
-    {
982
-        $date = $this->startDate->avoidMutation();
983
-
984
-        return $rounding ? $date->round($this->getDateInterval(), $rounding) : $date;
985
-    }
986
-
987
-    /**
988
-     * Get end date of the period.
989
-     *
990
-     * @param string|null $rounding Optional rounding 'floor', 'ceil', 'round' using the period interval.
991
-     *
992
-     * @return CarbonInterface|null
993
-     */
994
-    public function getEndDate(string $rounding = null)
995
-    {
996
-        if (!$this->endDate) {
997
-            return null;
998
-        }
999
-
1000
-        $date = $this->endDate->avoidMutation();
1001
-
1002
-        return $rounding ? $date->round($this->getDateInterval(), $rounding) : $date;
1003
-    }
1004
-
1005
-    /**
1006
-     * Get number of recurrences.
1007
-     *
1008
-     * @return int|float|null
1009
-     */
1010
-    public function getRecurrences()
1011
-    {
1012
-        return $this->recurrences;
1013
-    }
1014
-
1015
-    /**
1016
-     * Returns true if the start date should be excluded.
1017
-     *
1018
-     * @return bool
1019
-     */
1020
-    public function isStartExcluded()
1021
-    {
1022
-        return ($this->options & static::EXCLUDE_START_DATE) !== 0;
1023
-    }
1024
-
1025
-    /**
1026
-     * Returns true if the end date should be excluded.
1027
-     *
1028
-     * @return bool
1029
-     */
1030
-    public function isEndExcluded()
1031
-    {
1032
-        return ($this->options & static::EXCLUDE_END_DATE) !== 0;
1033
-    }
1034
-
1035
-    /**
1036
-     * Returns true if the start date should be included.
1037
-     *
1038
-     * @return bool
1039
-     */
1040
-    public function isStartIncluded()
1041
-    {
1042
-        return !$this->isStartExcluded();
1043
-    }
1044
-
1045
-    /**
1046
-     * Returns true if the end date should be included.
1047
-     *
1048
-     * @return bool
1049
-     */
1050
-    public function isEndIncluded()
1051
-    {
1052
-        return !$this->isEndExcluded();
1053
-    }
1054
-
1055
-    /**
1056
-     * Return the start if it's included by option, else return the start + 1 period interval.
1057
-     *
1058
-     * @return CarbonInterface
1059
-     */
1060
-    public function getIncludedStartDate()
1061
-    {
1062
-        $start = $this->getStartDate();
1063
-
1064
-        if ($this->isStartExcluded()) {
1065
-            return $start->add($this->getDateInterval());
1066
-        }
1067
-
1068
-        return $start;
1069
-    }
1070
-
1071
-    /**
1072
-     * Return the end if it's included by option, else return the end - 1 period interval.
1073
-     * Warning: if the period has no fixed end, this method will iterate the period to calculate it.
1074
-     *
1075
-     * @return CarbonInterface
1076
-     */
1077
-    public function getIncludedEndDate()
1078
-    {
1079
-        $end = $this->getEndDate();
1080
-
1081
-        if (!$end) {
1082
-            return $this->calculateEnd();
1083
-        }
1084
-
1085
-        if ($this->isEndExcluded()) {
1086
-            return $end->sub($this->getDateInterval());
1087
-        }
1088
-
1089
-        return $end;
1090
-    }
1091
-
1092
-    /**
1093
-     * Add a filter to the stack.
1094
-     *
1095
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
1096
-     *
1097
-     * @param callable $callback
1098
-     * @param string   $name
1099
-     *
1100
-     * @return $this
1101
-     */
1102
-    public function addFilter($callback, $name = null)
1103
-    {
1104
-        $tuple = $this->createFilterTuple(\func_get_args());
1105
-
1106
-        $this->filters[] = $tuple;
1107
-
1108
-        $this->handleChangedParameters();
1109
-
1110
-        return $this;
1111
-    }
1112
-
1113
-    /**
1114
-     * Prepend a filter to the stack.
1115
-     *
1116
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
1117
-     *
1118
-     * @param callable $callback
1119
-     * @param string   $name
1120
-     *
1121
-     * @return $this
1122
-     */
1123
-    public function prependFilter($callback, $name = null)
1124
-    {
1125
-        $tuple = $this->createFilterTuple(\func_get_args());
1126
-
1127
-        array_unshift($this->filters, $tuple);
1128
-
1129
-        $this->handleChangedParameters();
1130
-
1131
-        return $this;
1132
-    }
1133
-
1134
-    /**
1135
-     * Remove a filter by instance or name.
1136
-     *
1137
-     * @param callable|string $filter
1138
-     *
1139
-     * @return $this
1140
-     */
1141
-    public function removeFilter($filter)
1142
-    {
1143
-        $key = \is_callable($filter) ? 0 : 1;
1144
-
1145
-        $this->filters = array_values(array_filter(
1146
-            $this->filters,
1147
-            function ($tuple) use ($key, $filter) {
1148
-                return $tuple[$key] !== $filter;
1149
-            }
1150
-        ));
1151
-
1152
-        $this->updateInternalState();
1153
-
1154
-        $this->handleChangedParameters();
1155
-
1156
-        return $this;
1157
-    }
1158
-
1159
-    /**
1160
-     * Return whether given instance or name is in the filter stack.
1161
-     *
1162
-     * @param callable|string $filter
1163
-     *
1164
-     * @return bool
1165
-     */
1166
-    public function hasFilter($filter)
1167
-    {
1168
-        $key = \is_callable($filter) ? 0 : 1;
1169
-
1170
-        foreach ($this->filters as $tuple) {
1171
-            if ($tuple[$key] === $filter) {
1172
-                return true;
1173
-            }
1174
-        }
1175
-
1176
-        return false;
1177
-    }
1178
-
1179
-    /**
1180
-     * Get filters stack.
1181
-     *
1182
-     * @return array
1183
-     */
1184
-    public function getFilters()
1185
-    {
1186
-        return $this->filters;
1187
-    }
1188
-
1189
-    /**
1190
-     * Set filters stack.
1191
-     *
1192
-     * @param array $filters
1193
-     *
1194
-     * @return $this
1195
-     */
1196
-    public function setFilters(array $filters)
1197
-    {
1198
-        $this->filters = $filters;
1199
-
1200
-        $this->updateInternalState();
1201
-
1202
-        $this->handleChangedParameters();
1203
-
1204
-        return $this;
1205
-    }
1206
-
1207
-    /**
1208
-     * Reset filters stack.
1209
-     *
1210
-     * @return $this
1211
-     */
1212
-    public function resetFilters()
1213
-    {
1214
-        $this->filters = [];
1215
-
1216
-        if ($this->endDate !== null) {
1217
-            $this->filters[] = [static::END_DATE_FILTER, null];
1218
-        }
1219
-
1220
-        if ($this->recurrences !== null) {
1221
-            $this->filters[] = [static::RECURRENCES_FILTER, null];
1222
-        }
1223
-
1224
-        $this->handleChangedParameters();
1225
-
1226
-        return $this;
1227
-    }
1228
-
1229
-    /**
1230
-     * Add a recurrences filter (set maximum number of recurrences).
1231
-     *
1232
-     * @param int|float|null $recurrences
1233
-     *
1234
-     * @throws InvalidArgumentException
1235
-     *
1236
-     * @return $this
1237
-     */
1238
-    public function setRecurrences($recurrences)
1239
-    {
1240
-        if ((!is_numeric($recurrences) && $recurrences !== null) || $recurrences < 0) {
1241
-            throw new InvalidPeriodParameterException('Invalid number of recurrences.');
1242
-        }
1243
-
1244
-        if ($recurrences === null) {
1245
-            return $this->removeFilter(static::RECURRENCES_FILTER);
1246
-        }
1247
-
1248
-        $this->recurrences = $recurrences === INF ? INF : (int) $recurrences;
1249
-
1250
-        if (!$this->hasFilter(static::RECURRENCES_FILTER)) {
1251
-            return $this->addFilter(static::RECURRENCES_FILTER);
1252
-        }
1253
-
1254
-        $this->handleChangedParameters();
1255
-
1256
-        return $this;
1257
-    }
1258
-
1259
-    /**
1260
-     * Change the period start date.
1261
-     *
1262
-     * @param DateTime|DateTimeInterface|string $date
1263
-     * @param bool|null                         $inclusive
1264
-     *
1265
-     * @throws InvalidPeriodDateException
1266
-     *
1267
-     * @return $this
1268
-     */
1269
-    public function setStartDate($date, $inclusive = null)
1270
-    {
1271
-        if (!$this->isInfiniteDate($date) && !($date = ([$this->dateClass, 'make'])($date))) {
1272
-            throw new InvalidPeriodDateException('Invalid start date.');
1273
-        }
1274
-
1275
-        $this->startDate = $date;
1276
-
1277
-        if ($inclusive !== null) {
1278
-            $this->toggleOptions(static::EXCLUDE_START_DATE, !$inclusive);
1279
-        }
1280
-
1281
-        return $this;
1282
-    }
1283
-
1284
-    /**
1285
-     * Change the period end date.
1286
-     *
1287
-     * @param DateTime|DateTimeInterface|string|null $date
1288
-     * @param bool|null                              $inclusive
1289
-     *
1290
-     * @throws \InvalidArgumentException
1291
-     *
1292
-     * @return $this
1293
-     */
1294
-    public function setEndDate($date, $inclusive = null)
1295
-    {
1296
-        if ($date !== null && !$this->isInfiniteDate($date) && !$date = ([$this->dateClass, 'make'])($date)) {
1297
-            throw new InvalidPeriodDateException('Invalid end date.');
1298
-        }
1299
-
1300
-        if (!$date) {
1301
-            return $this->removeFilter(static::END_DATE_FILTER);
1302
-        }
1303
-
1304
-        $this->endDate = $date;
1305
-
1306
-        if ($inclusive !== null) {
1307
-            $this->toggleOptions(static::EXCLUDE_END_DATE, !$inclusive);
1308
-        }
1309
-
1310
-        if (!$this->hasFilter(static::END_DATE_FILTER)) {
1311
-            return $this->addFilter(static::END_DATE_FILTER);
1312
-        }
1313
-
1314
-        $this->handleChangedParameters();
1315
-
1316
-        return $this;
1317
-    }
1318
-
1319
-    /**
1320
-     * Check if the current position is valid.
1321
-     *
1322
-     * @return bool
1323
-     */
1324
-    #[ReturnTypeWillChange]
1325
-    public function valid()
1326
-    {
1327
-        return $this->validateCurrentDate() === true;
1328
-    }
1329
-
1330
-    /**
1331
-     * Return the current key.
1332
-     *
1333
-     * @return int|null
1334
-     */
1335
-    #[ReturnTypeWillChange]
1336
-    public function key()
1337
-    {
1338
-        return $this->valid()
1339
-            ? $this->key
1340
-            : null;
1341
-    }
1342
-
1343
-    /**
1344
-     * Return the current date.
1345
-     *
1346
-     * @return CarbonInterface|null
1347
-     */
1348
-    #[ReturnTypeWillChange]
1349
-    public function current()
1350
-    {
1351
-        return $this->valid()
1352
-            ? $this->prepareForReturn($this->current)
1353
-            : null;
1354
-    }
1355
-
1356
-    /**
1357
-     * Move forward to the next date.
1358
-     *
1359
-     * @throws RuntimeException
1360
-     *
1361
-     * @return void
1362
-     */
1363
-    #[ReturnTypeWillChange]
1364
-    public function next()
1365
-    {
1366
-        if ($this->current === null) {
1367
-            $this->rewind();
1368
-        }
1369
-
1370
-        if ($this->validationResult !== static::END_ITERATION) {
1371
-            $this->key++;
1372
-
1373
-            $this->incrementCurrentDateUntilValid();
1374
-        }
1375
-    }
1376
-
1377
-    /**
1378
-     * Rewind to the start date.
1379
-     *
1380
-     * Iterating over a date in the UTC timezone avoids bug during backward DST change.
1381
-     *
1382
-     * @see https://bugs.php.net/bug.php?id=72255
1383
-     * @see https://bugs.php.net/bug.php?id=74274
1384
-     * @see https://wiki.php.net/rfc/datetime_and_daylight_saving_time
1385
-     *
1386
-     * @throws RuntimeException
1387
-     *
1388
-     * @return void
1389
-     */
1390
-    #[ReturnTypeWillChange]
1391
-    public function rewind()
1392
-    {
1393
-        $this->key = 0;
1394
-        $this->current = ([$this->dateClass, 'make'])($this->startDate);
1395
-        $settings = $this->getSettings();
1396
-
1397
-        if ($this->hasLocalTranslator()) {
1398
-            $settings['locale'] = $this->getTranslatorLocale();
1399
-        }
1400
-
1401
-        $this->current->settings($settings);
1402
-        $this->timezone = static::intervalHasTime($this->dateInterval) ? $this->current->getTimezone() : null;
1403
-
1404
-        if ($this->timezone) {
1405
-            $this->current = $this->current->utc();
1406
-        }
1407
-
1408
-        $this->validationResult = null;
1409
-
1410
-        if ($this->isStartExcluded() || $this->validateCurrentDate() === false) {
1411
-            $this->incrementCurrentDateUntilValid();
1412
-        }
1413
-    }
1414
-
1415
-    /**
1416
-     * Skip iterations and returns iteration state (false if ended, true if still valid).
1417
-     *
1418
-     * @param int $count steps number to skip (1 by default)
1419
-     *
1420
-     * @return bool
1421
-     */
1422
-    public function skip($count = 1)
1423
-    {
1424
-        for ($i = $count; $this->valid() && $i > 0; $i--) {
1425
-            $this->next();
1426
-        }
1427
-
1428
-        return $this->valid();
1429
-    }
1430
-
1431
-    /**
1432
-     * Format the date period as ISO 8601.
1433
-     *
1434
-     * @return string
1435
-     */
1436
-    public function toIso8601String()
1437
-    {
1438
-        $parts = [];
1439
-
1440
-        if ($this->recurrences !== null) {
1441
-            $parts[] = 'R'.$this->recurrences;
1442
-        }
1443
-
1444
-        $parts[] = $this->startDate->toIso8601String();
1445
-
1446
-        $parts[] = $this->dateInterval->spec();
1447
-
1448
-        if ($this->endDate !== null) {
1449
-            $parts[] = $this->endDate->toIso8601String();
1450
-        }
1451
-
1452
-        return implode('/', $parts);
1453
-    }
1454
-
1455
-    /**
1456
-     * Convert the date period into a string.
1457
-     *
1458
-     * @return string
1459
-     */
1460
-    public function toString()
1461
-    {
1462
-        $translator = ([$this->dateClass, 'getTranslator'])();
1463
-
1464
-        $parts = [];
1465
-
1466
-        $format = !$this->startDate->isStartOfDay() || ($this->endDate && !$this->endDate->isStartOfDay())
1467
-            ? 'Y-m-d H:i:s'
1468
-            : 'Y-m-d';
1469
-
1470
-        if ($this->recurrences !== null) {
1471
-            $parts[] = $this->translate('period_recurrences', [], $this->recurrences, $translator);
1472
-        }
1473
-
1474
-        $parts[] = $this->translate('period_interval', [':interval' => $this->dateInterval->forHumans([
1475
-            'join' => true,
1476
-        ])], null, $translator);
1477
-
1478
-        $parts[] = $this->translate('period_start_date', [':date' => $this->startDate->rawFormat($format)], null, $translator);
1479
-
1480
-        if ($this->endDate !== null) {
1481
-            $parts[] = $this->translate('period_end_date', [':date' => $this->endDate->rawFormat($format)], null, $translator);
1482
-        }
1483
-
1484
-        $result = implode(' ', $parts);
1485
-
1486
-        return mb_strtoupper(mb_substr($result, 0, 1)).mb_substr($result, 1);
1487
-    }
1488
-
1489
-    /**
1490
-     * Format the date period as ISO 8601.
1491
-     *
1492
-     * @return string
1493
-     */
1494
-    public function spec()
1495
-    {
1496
-        return $this->toIso8601String();
1497
-    }
1498
-
1499
-    /**
1500
-     * Cast the current instance into the given class.
1501
-     *
1502
-     * @param string $className The $className::instance() method will be called to cast the current object.
1503
-     *
1504
-     * @return DatePeriod
1505
-     */
1506
-    public function cast(string $className)
1507
-    {
1508
-        if (!method_exists($className, 'instance')) {
1509
-            if (is_a($className, DatePeriod::class, true)) {
1510
-                return new $className(
1511
-                    $this->rawDate($this->getStartDate()),
1512
-                    $this->getDateInterval(),
1513
-                    $this->getEndDate() ? $this->rawDate($this->getIncludedEndDate()) : $this->getRecurrences(),
1514
-                    $this->isStartExcluded() ? DatePeriod::EXCLUDE_START_DATE : 0
1515
-                );
1516
-            }
1517
-
1518
-            throw new InvalidCastException("$className has not the instance() method needed to cast the date.");
1519
-        }
1520
-
1521
-        return $className::instance($this);
1522
-    }
1523
-
1524
-    /**
1525
-     * Return native DatePeriod PHP object matching the current instance.
1526
-     *
1527
-     * @example
1528
-     * ```
1529
-     * var_dump(CarbonPeriod::create('2021-01-05', '2021-02-15')->toDatePeriod());
1530
-     * ```
1531
-     *
1532
-     * @return DatePeriod
1533
-     */
1534
-    public function toDatePeriod()
1535
-    {
1536
-        return $this->cast(DatePeriod::class);
1537
-    }
1538
-
1539
-    /**
1540
-     * Return `true` if the period has no custom filter and is guaranteed to be endless.
1541
-     *
1542
-     * Note that we can't check if a period is endless as soon as it has custom filters
1543
-     * because filters can emit `CarbonPeriod::END_ITERATION` to stop the iteration in
1544
-     * a way we can't predict without actually iterating the period.
1545
-     */
1546
-    public function isUnfilteredAndEndLess(): bool
1547
-    {
1548
-        foreach ($this->filters as $filter) {
1549
-            switch ($filter) {
1550
-                case [static::RECURRENCES_FILTER, null]:
1551
-                    if ($this->recurrences !== null && is_finite($this->recurrences)) {
1552
-                        return false;
1553
-                    }
1554
-
1555
-                    break;
1556
-
1557
-                case [static::END_DATE_FILTER, null]:
1558
-                    if ($this->endDate !== null && !$this->endDate->isEndOfTime()) {
1559
-                        return false;
1560
-                    }
1561
-
1562
-                    break;
1563
-
1564
-                default:
1565
-                    return false;
1566
-            }
1567
-        }
1568
-
1569
-        return true;
1570
-    }
1571
-
1572
-    /**
1573
-     * Convert the date period into an array without changing current iteration state.
1574
-     *
1575
-     * @return CarbonInterface[]
1576
-     */
1577
-    public function toArray()
1578
-    {
1579
-        if ($this->isUnfilteredAndEndLess()) {
1580
-            throw new EndLessPeriodException("Endless period can't be converted to array nor counted.");
1581
-        }
1582
-
1583
-        $state = [
1584
-            $this->key,
1585
-            $this->current ? $this->current->avoidMutation() : null,
1586
-            $this->validationResult,
1587
-        ];
1588
-
1589
-        $result = iterator_to_array($this);
1590
-
1591
-        [$this->key, $this->current, $this->validationResult] = $state;
1592
-
1593
-        return $result;
1594
-    }
1595
-
1596
-    /**
1597
-     * Count dates in the date period.
1598
-     *
1599
-     * @return int
1600
-     */
1601
-    #[ReturnTypeWillChange]
1602
-    public function count()
1603
-    {
1604
-        return \count($this->toArray());
1605
-    }
1606
-
1607
-    /**
1608
-     * Return the first date in the date period.
1609
-     *
1610
-     * @return CarbonInterface|null
1611
-     */
1612
-    public function first()
1613
-    {
1614
-        if ($this->isUnfilteredAndEndLess()) {
1615
-            foreach ($this as $date) {
1616
-                $this->rewind();
1617
-
1618
-                return $date;
1619
-            }
1620
-
1621
-            return null;
1622
-        }
1623
-
1624
-        return ($this->toArray() ?: [])[0] ?? null;
1625
-    }
1626
-
1627
-    /**
1628
-     * Return the last date in the date period.
1629
-     *
1630
-     * @return CarbonInterface|null
1631
-     */
1632
-    public function last()
1633
-    {
1634
-        $array = $this->toArray();
1635
-
1636
-        return $array ? $array[\count($array) - 1] : null;
1637
-    }
1638
-
1639
-    /**
1640
-     * Convert the date period into a string.
1641
-     *
1642
-     * @return string
1643
-     */
1644
-    public function __toString()
1645
-    {
1646
-        return $this->toString();
1647
-    }
1648
-
1649
-    /**
1650
-     * Add aliases for setters.
1651
-     *
1652
-     * CarbonPeriod::days(3)->hours(5)->invert()
1653
-     *     ->sinceNow()->until('2010-01-10')
1654
-     *     ->filter(...)
1655
-     *     ->count()
1656
-     *
1657
-     * Note: We use magic method to let static and instance aliases with the same names.
1658
-     *
1659
-     * @param string $method
1660
-     * @param array  $parameters
1661
-     *
1662
-     * @return mixed
1663
-     */
1664
-    public function __call($method, $parameters)
1665
-    {
1666
-        if (static::hasMacro($method)) {
1667
-            return static::bindMacroContext($this, function () use (&$method, &$parameters) {
1668
-                return $this->callMacro($method, $parameters);
1669
-            });
1670
-        }
1671
-
1672
-        $roundedValue = $this->callRoundMethod($method, $parameters);
1673
-
1674
-        if ($roundedValue !== null) {
1675
-            return $roundedValue;
1676
-        }
1677
-
1678
-        $first = \count($parameters) >= 1 ? $parameters[0] : null;
1679
-        $second = \count($parameters) >= 2 ? $parameters[1] : null;
1680
-
1681
-        switch ($method) {
1682
-            case 'start':
1683
-            case 'since':
1684
-                return $this->setStartDate($first, $second);
1685
-
1686
-            case 'sinceNow':
1687
-                return $this->setStartDate(new Carbon(), $first);
1688
-
1689
-            case 'end':
1690
-            case 'until':
1691
-                return $this->setEndDate($first, $second);
1692
-
1693
-            case 'untilNow':
1694
-                return $this->setEndDate(new Carbon(), $first);
1695
-
1696
-            case 'dates':
1697
-            case 'between':
1698
-                return $this->setDates($first, $second);
1699
-
1700
-            case 'recurrences':
1701
-            case 'times':
1702
-                return $this->setRecurrences($first);
1703
-
1704
-            case 'options':
1705
-                return $this->setOptions($first);
1706
-
1707
-            case 'toggle':
1708
-                return $this->toggleOptions($first, $second);
1709
-
1710
-            case 'filter':
1711
-            case 'push':
1712
-                return $this->addFilter($first, $second);
1713
-
1714
-            case 'prepend':
1715
-                return $this->prependFilter($first, $second);
1716
-
1717
-            case 'filters':
1718
-                return $this->setFilters($first ?: []);
1719
-
1720
-            case 'interval':
1721
-            case 'each':
1722
-            case 'every':
1723
-            case 'step':
1724
-            case 'stepBy':
1725
-                return $this->setDateInterval($first);
1726
-
1727
-            case 'invert':
1728
-                return $this->invertDateInterval();
1729
-
1730
-            case 'years':
1731
-            case 'year':
1732
-            case 'months':
1733
-            case 'month':
1734
-            case 'weeks':
1735
-            case 'week':
1736
-            case 'days':
1737
-            case 'dayz':
1738
-            case 'day':
1739
-            case 'hours':
1740
-            case 'hour':
1741
-            case 'minutes':
1742
-            case 'minute':
1743
-            case 'seconds':
1744
-            case 'second':
1745
-                return $this->setDateInterval((
1746
-                    // Override default P1D when instantiating via fluent setters.
1747
-                    [$this->isDefaultInterval ? new CarbonInterval('PT0S') : $this->dateInterval, $method]
1748
-                )(
1749
-                    \count($parameters) === 0 ? 1 : $first
1750
-                ));
1751
-        }
1752
-
1753
-        if ($this->localStrictModeEnabled ?? Carbon::isStrictModeEnabled()) {
1754
-            throw new UnknownMethodException($method);
1755
-        }
1756
-
1757
-        return $this;
1758
-    }
1759
-
1760
-    /**
1761
-     * Set the instance's timezone from a string or object and apply it to start/end.
1762
-     *
1763
-     * @param \DateTimeZone|string $timezone
1764
-     *
1765
-     * @return static
1766
-     */
1767
-    public function setTimezone($timezone)
1768
-    {
1769
-        $this->tzName = $timezone;
1770
-        $this->timezone = $timezone;
1771
-
1772
-        if ($this->startDate) {
1773
-            $this->setStartDate($this->startDate->setTimezone($timezone));
1774
-        }
1775
-
1776
-        if ($this->endDate) {
1777
-            $this->setEndDate($this->endDate->setTimezone($timezone));
1778
-        }
1779
-
1780
-        return $this;
1781
-    }
1782
-
1783
-    /**
1784
-     * Set the instance's timezone from a string or object and add/subtract the offset difference to start/end.
1785
-     *
1786
-     * @param \DateTimeZone|string $timezone
1787
-     *
1788
-     * @return static
1789
-     */
1790
-    public function shiftTimezone($timezone)
1791
-    {
1792
-        $this->tzName = $timezone;
1793
-        $this->timezone = $timezone;
1794
-
1795
-        if ($this->startDate) {
1796
-            $this->setStartDate($this->startDate->shiftTimezone($timezone));
1797
-        }
1798
-
1799
-        if ($this->endDate) {
1800
-            $this->setEndDate($this->endDate->shiftTimezone($timezone));
1801
-        }
1802
-
1803
-        return $this;
1804
-    }
1805
-
1806
-    /**
1807
-     * Returns the end is set, else calculated from start an recurrences.
1808
-     *
1809
-     * @param string|null $rounding Optional rounding 'floor', 'ceil', 'round' using the period interval.
1810
-     *
1811
-     * @return CarbonInterface
1812
-     */
1813
-    public function calculateEnd(string $rounding = null)
1814
-    {
1815
-        if ($end = $this->getEndDate($rounding)) {
1816
-            return $end;
1817
-        }
1818
-
1819
-        if ($this->dateInterval->isEmpty()) {
1820
-            return $this->getStartDate($rounding);
1821
-        }
1822
-
1823
-        $date = $this->getEndFromRecurrences() ?? $this->iterateUntilEnd();
1824
-
1825
-        if ($date && $rounding) {
1826
-            $date = $date->avoidMutation()->round($this->getDateInterval(), $rounding);
1827
-        }
1828
-
1829
-        return $date;
1830
-    }
1831
-
1832
-    /**
1833
-     * @return CarbonInterface|null
1834
-     */
1835
-    private function getEndFromRecurrences()
1836
-    {
1837
-        if ($this->recurrences === null) {
1838
-            throw new UnreachableException(
1839
-                "Could not calculate period end without either explicit end or recurrences.\n".
1840
-                "If you're looking for a forever-period, use ->setRecurrences(INF)."
1841
-            );
1842
-        }
1843
-
1844
-        if ($this->recurrences === INF) {
1845
-            $start = $this->getStartDate();
1846
-
1847
-            return $start < $start->avoidMutation()->add($this->getDateInterval())
1848
-                ? CarbonImmutable::endOfTime()
1849
-                : CarbonImmutable::startOfTime();
1850
-        }
1851
-
1852
-        if ($this->filters === [[static::RECURRENCES_FILTER, null]]) {
1853
-            return $this->getStartDate()->avoidMutation()->add(
1854
-                $this->getDateInterval()->times(
1855
-                    $this->recurrences - ($this->isStartExcluded() ? 0 : 1)
1856
-                )
1857
-            );
1858
-        }
1859
-
1860
-        return null;
1861
-    }
1862
-
1863
-    /**
1864
-     * @return CarbonInterface|null
1865
-     */
1866
-    private function iterateUntilEnd()
1867
-    {
1868
-        $attempts = 0;
1869
-        $date = null;
1870
-
1871
-        foreach ($this as $date) {
1872
-            if (++$attempts > static::END_MAX_ATTEMPTS) {
1873
-                throw new UnreachableException(
1874
-                    'Could not calculate period end after iterating '.static::END_MAX_ATTEMPTS.' times.'
1875
-                );
1876
-            }
1877
-        }
1878
-
1879
-        return $date;
1880
-    }
1881
-
1882
-    /**
1883
-     * Returns true if the current period overlaps the given one (if 1 parameter passed)
1884
-     * or the period between 2 dates (if 2 parameters passed).
1885
-     *
1886
-     * @param CarbonPeriod|\DateTimeInterface|Carbon|CarbonImmutable|string $rangeOrRangeStart
1887
-     * @param \DateTimeInterface|Carbon|CarbonImmutable|string|null         $rangeEnd
1888
-     *
1889
-     * @return bool
1890
-     */
1891
-    public function overlaps($rangeOrRangeStart, $rangeEnd = null)
1892
-    {
1893
-        $range = $rangeEnd ? static::create($rangeOrRangeStart, $rangeEnd) : $rangeOrRangeStart;
1894
-
1895
-        if (!($range instanceof self)) {
1896
-            $range = static::create($range);
1897
-        }
1898
-
1899
-        [$start, $end] = $this->orderCouple($this->getStartDate(), $this->calculateEnd());
1900
-        [$rangeStart, $rangeEnd] = $this->orderCouple($range->getStartDate(), $range->calculateEnd());
1901
-
1902
-        return $end > $rangeStart && $rangeEnd > $start;
1903
-    }
1904
-
1905
-    /**
1906
-     * Execute a given function on each date of the period.
1907
-     *
1908
-     * @example
1909
-     * ```
1910
-     * Carbon::create('2020-11-29')->daysUntil('2020-12-24')->forEach(function (Carbon $date) {
1911
-     *   echo $date->diffInDays('2020-12-25')." days before Christmas!\n";
1912
-     * });
1913
-     * ```
1914
-     *
1915
-     * @param callable $callback
1916
-     */
1917
-    public function forEach(callable $callback)
1918
-    {
1919
-        foreach ($this as $date) {
1920
-            $callback($date);
1921
-        }
1922
-    }
1923
-
1924
-    /**
1925
-     * Execute a given function on each date of the period and yield the result of this function.
1926
-     *
1927
-     * @example
1928
-     * ```
1929
-     * $period = Carbon::create('2020-11-29')->daysUntil('2020-12-24');
1930
-     * echo implode("\n", iterator_to_array($period->map(function (Carbon $date) {
1931
-     *   return $date->diffInDays('2020-12-25').' days before Christmas!';
1932
-     * })));
1933
-     * ```
1934
-     *
1935
-     * @param callable $callback
1936
-     *
1937
-     * @return \Generator
1938
-     */
1939
-    public function map(callable $callback)
1940
-    {
1941
-        foreach ($this as $date) {
1942
-            yield $callback($date);
1943
-        }
1944
-    }
1945
-
1946
-    /**
1947
-     * Determines if the instance is equal to another.
1948
-     * Warning: if options differ, instances wil never be equal.
1949
-     *
1950
-     * @param mixed $period
1951
-     *
1952
-     * @see equalTo()
1953
-     *
1954
-     * @return bool
1955
-     */
1956
-    public function eq($period): bool
1957
-    {
1958
-        return $this->equalTo($period);
1959
-    }
1960
-
1961
-    /**
1962
-     * Determines if the instance is equal to another.
1963
-     * Warning: if options differ, instances wil never be equal.
1964
-     *
1965
-     * @param mixed $period
1966
-     *
1967
-     * @return bool
1968
-     */
1969
-    public function equalTo($period): bool
1970
-    {
1971
-        if (!($period instanceof self)) {
1972
-            $period = self::make($period);
1973
-        }
1974
-
1975
-        $end = $this->getEndDate();
1976
-
1977
-        return $period !== null
1978
-            && $this->getDateInterval()->eq($period->getDateInterval())
1979
-            && $this->getStartDate()->eq($period->getStartDate())
1980
-            && ($end ? $end->eq($period->getEndDate()) : $this->getRecurrences() === $period->getRecurrences())
1981
-            && ($this->getOptions() & (~static::IMMUTABLE)) === ($period->getOptions() & (~static::IMMUTABLE));
1982
-    }
1983
-
1984
-    /**
1985
-     * Determines if the instance is not equal to another.
1986
-     * Warning: if options differ, instances wil never be equal.
1987
-     *
1988
-     * @param mixed $period
1989
-     *
1990
-     * @see notEqualTo()
1991
-     *
1992
-     * @return bool
1993
-     */
1994
-    public function ne($period): bool
1995
-    {
1996
-        return $this->notEqualTo($period);
1997
-    }
1998
-
1999
-    /**
2000
-     * Determines if the instance is not equal to another.
2001
-     * Warning: if options differ, instances wil never be equal.
2002
-     *
2003
-     * @param mixed $period
2004
-     *
2005
-     * @return bool
2006
-     */
2007
-    public function notEqualTo($period): bool
2008
-    {
2009
-        return !$this->eq($period);
2010
-    }
2011
-
2012
-    /**
2013
-     * Determines if the start date is before an other given date.
2014
-     * (Rather start/end are included by options is ignored.)
2015
-     *
2016
-     * @param mixed $date
2017
-     *
2018
-     * @return bool
2019
-     */
2020
-    public function startsBefore($date = null): bool
2021
-    {
2022
-        return $this->getStartDate()->lessThan($this->resolveCarbon($date));
2023
-    }
2024
-
2025
-    /**
2026
-     * Determines if the start date is before or the same as a given date.
2027
-     * (Rather start/end are included by options is ignored.)
2028
-     *
2029
-     * @param mixed $date
2030
-     *
2031
-     * @return bool
2032
-     */
2033
-    public function startsBeforeOrAt($date = null): bool
2034
-    {
2035
-        return $this->getStartDate()->lessThanOrEqualTo($this->resolveCarbon($date));
2036
-    }
2037
-
2038
-    /**
2039
-     * Determines if the start date is after an other given date.
2040
-     * (Rather start/end are included by options is ignored.)
2041
-     *
2042
-     * @param mixed $date
2043
-     *
2044
-     * @return bool
2045
-     */
2046
-    public function startsAfter($date = null): bool
2047
-    {
2048
-        return $this->getStartDate()->greaterThan($this->resolveCarbon($date));
2049
-    }
2050
-
2051
-    /**
2052
-     * Determines if the start date is after or the same as a given date.
2053
-     * (Rather start/end are included by options is ignored.)
2054
-     *
2055
-     * @param mixed $date
2056
-     *
2057
-     * @return bool
2058
-     */
2059
-    public function startsAfterOrAt($date = null): bool
2060
-    {
2061
-        return $this->getStartDate()->greaterThanOrEqualTo($this->resolveCarbon($date));
2062
-    }
2063
-
2064
-    /**
2065
-     * Determines if the start date is the same as a given date.
2066
-     * (Rather start/end are included by options is ignored.)
2067
-     *
2068
-     * @param mixed $date
2069
-     *
2070
-     * @return bool
2071
-     */
2072
-    public function startsAt($date = null): bool
2073
-    {
2074
-        return $this->getStartDate()->equalTo($this->resolveCarbon($date));
2075
-    }
2076
-
2077
-    /**
2078
-     * Determines if the end date is before an other given date.
2079
-     * (Rather start/end are included by options is ignored.)
2080
-     *
2081
-     * @param mixed $date
2082
-     *
2083
-     * @return bool
2084
-     */
2085
-    public function endsBefore($date = null): bool
2086
-    {
2087
-        return $this->calculateEnd()->lessThan($this->resolveCarbon($date));
2088
-    }
2089
-
2090
-    /**
2091
-     * Determines if the end date is before or the same as a given date.
2092
-     * (Rather start/end are included by options is ignored.)
2093
-     *
2094
-     * @param mixed $date
2095
-     *
2096
-     * @return bool
2097
-     */
2098
-    public function endsBeforeOrAt($date = null): bool
2099
-    {
2100
-        return $this->calculateEnd()->lessThanOrEqualTo($this->resolveCarbon($date));
2101
-    }
2102
-
2103
-    /**
2104
-     * Determines if the end date is after an other given date.
2105
-     * (Rather start/end are included by options is ignored.)
2106
-     *
2107
-     * @param mixed $date
2108
-     *
2109
-     * @return bool
2110
-     */
2111
-    public function endsAfter($date = null): bool
2112
-    {
2113
-        return $this->calculateEnd()->greaterThan($this->resolveCarbon($date));
2114
-    }
2115
-
2116
-    /**
2117
-     * Determines if the end date is after or the same as a given date.
2118
-     * (Rather start/end are included by options is ignored.)
2119
-     *
2120
-     * @param mixed $date
2121
-     *
2122
-     * @return bool
2123
-     */
2124
-    public function endsAfterOrAt($date = null): bool
2125
-    {
2126
-        return $this->calculateEnd()->greaterThanOrEqualTo($this->resolveCarbon($date));
2127
-    }
2128
-
2129
-    /**
2130
-     * Determines if the end date is the same as a given date.
2131
-     * (Rather start/end are included by options is ignored.)
2132
-     *
2133
-     * @param mixed $date
2134
-     *
2135
-     * @return bool
2136
-     */
2137
-    public function endsAt($date = null): bool
2138
-    {
2139
-        return $this->calculateEnd()->equalTo($this->resolveCarbon($date));
2140
-    }
2141
-
2142
-    /**
2143
-     * Return true if start date is now or later.
2144
-     * (Rather start/end are included by options is ignored.)
2145
-     *
2146
-     * @return bool
2147
-     */
2148
-    public function isStarted(): bool
2149
-    {
2150
-        return $this->startsBeforeOrAt();
2151
-    }
2152
-
2153
-    /**
2154
-     * Return true if end date is now or later.
2155
-     * (Rather start/end are included by options is ignored.)
2156
-     *
2157
-     * @return bool
2158
-     */
2159
-    public function isEnded(): bool
2160
-    {
2161
-        return $this->endsBeforeOrAt();
2162
-    }
2163
-
2164
-    /**
2165
-     * Return true if now is between start date (included) and end date (excluded).
2166
-     * (Rather start/end are included by options is ignored.)
2167
-     *
2168
-     * @return bool
2169
-     */
2170
-    public function isInProgress(): bool
2171
-    {
2172
-        return $this->isStarted() && !$this->isEnded();
2173
-    }
2174
-
2175
-    /**
2176
-     * Round the current instance at the given unit with given precision if specified and the given function.
2177
-     *
2178
-     * @param string                              $unit
2179
-     * @param float|int|string|\DateInterval|null $precision
2180
-     * @param string                              $function
2181
-     *
2182
-     * @return $this
2183
-     */
2184
-    public function roundUnit($unit, $precision = 1, $function = 'round')
2185
-    {
2186
-        $this->setStartDate($this->getStartDate()->roundUnit($unit, $precision, $function));
2187
-
2188
-        if ($this->endDate) {
2189
-            $this->setEndDate($this->getEndDate()->roundUnit($unit, $precision, $function));
2190
-        }
2191
-
2192
-        $this->setDateInterval($this->getDateInterval()->roundUnit($unit, $precision, $function));
2193
-
2194
-        return $this;
2195
-    }
2196
-
2197
-    /**
2198
-     * Truncate the current instance at the given unit with given precision if specified.
2199
-     *
2200
-     * @param string                              $unit
2201
-     * @param float|int|string|\DateInterval|null $precision
2202
-     *
2203
-     * @return $this
2204
-     */
2205
-    public function floorUnit($unit, $precision = 1)
2206
-    {
2207
-        return $this->roundUnit($unit, $precision, 'floor');
2208
-    }
2209
-
2210
-    /**
2211
-     * Ceil the current instance at the given unit with given precision if specified.
2212
-     *
2213
-     * @param string                              $unit
2214
-     * @param float|int|string|\DateInterval|null $precision
2215
-     *
2216
-     * @return $this
2217
-     */
2218
-    public function ceilUnit($unit, $precision = 1)
2219
-    {
2220
-        return $this->roundUnit($unit, $precision, 'ceil');
2221
-    }
2222
-
2223
-    /**
2224
-     * Round the current instance second with given precision if specified (else period interval is used).
2225
-     *
2226
-     * @param float|int|string|\DateInterval|null $precision
2227
-     * @param string                              $function
2228
-     *
2229
-     * @return $this
2230
-     */
2231
-    public function round($precision = null, $function = 'round')
2232
-    {
2233
-        return $this->roundWith(
2234
-            $precision ?? $this->getDateInterval()->setLocalTranslator(TranslatorImmutable::get('en'))->forHumans(),
2235
-            $function
2236
-        );
2237
-    }
2238
-
2239
-    /**
2240
-     * Round the current instance second with given precision if specified (else period interval is used).
2241
-     *
2242
-     * @param float|int|string|\DateInterval|null $precision
2243
-     *
2244
-     * @return $this
2245
-     */
2246
-    public function floor($precision = null)
2247
-    {
2248
-        return $this->round($precision, 'floor');
2249
-    }
2250
-
2251
-    /**
2252
-     * Ceil the current instance second with given precision if specified (else period interval is used).
2253
-     *
2254
-     * @param float|int|string|\DateInterval|null $precision
2255
-     *
2256
-     * @return $this
2257
-     */
2258
-    public function ceil($precision = null)
2259
-    {
2260
-        return $this->round($precision, 'ceil');
2261
-    }
2262
-
2263
-    /**
2264
-     * Specify data which should be serialized to JSON.
2265
-     *
2266
-     * @link https://php.net/manual/en/jsonserializable.jsonserialize.php
2267
-     *
2268
-     * @return CarbonInterface[]
2269
-     */
2270
-    #[ReturnTypeWillChange]
2271
-    public function jsonSerialize()
2272
-    {
2273
-        return $this->toArray();
2274
-    }
2275
-
2276
-    /**
2277
-     * Return true if the given date is between start and end.
2278
-     *
2279
-     * @param \Carbon\Carbon|\Carbon\CarbonPeriod|\Carbon\CarbonInterval|\DateInterval|\DatePeriod|\DateTimeInterface|string|null $date
2280
-     *
2281
-     * @return bool
2282
-     */
2283
-    public function contains($date = null): bool
2284
-    {
2285
-        $startMethod = 'startsBefore'.($this->isStartIncluded() ? 'OrAt' : '');
2286
-        $endMethod = 'endsAfter'.($this->isEndIncluded() ? 'OrAt' : '');
2287
-
2288
-        return $this->$startMethod($date) && $this->$endMethod($date);
2289
-    }
2290
-
2291
-    /**
2292
-     * Return true if the current period follows a given other period (with no overlap).
2293
-     * For instance, [2019-08-01 -> 2019-08-12] follows [2019-07-29 -> 2019-07-31]
2294
-     * Note than in this example, follows() would be false if 2019-08-01 or 2019-07-31 was excluded by options.
2295
-     *
2296
-     * @param \Carbon\CarbonPeriod|\DatePeriod|string $period
2297
-     *
2298
-     * @return bool
2299
-     */
2300
-    public function follows($period, ...$arguments): bool
2301
-    {
2302
-        $period = $this->resolveCarbonPeriod($period, ...$arguments);
2303
-
2304
-        return $this->getIncludedStartDate()->equalTo($period->getIncludedEndDate()->add($period->getDateInterval()));
2305
-    }
2306
-
2307
-    /**
2308
-     * Return true if the given other period follows the current one (with no overlap).
2309
-     * For instance, [2019-07-29 -> 2019-07-31] is followed by [2019-08-01 -> 2019-08-12]
2310
-     * Note than in this example, isFollowedBy() would be false if 2019-08-01 or 2019-07-31 was excluded by options.
2311
-     *
2312
-     * @param \Carbon\CarbonPeriod|\DatePeriod|string $period
2313
-     *
2314
-     * @return bool
2315
-     */
2316
-    public function isFollowedBy($period, ...$arguments): bool
2317
-    {
2318
-        $period = $this->resolveCarbonPeriod($period, ...$arguments);
2319
-
2320
-        return $period->follows($this);
2321
-    }
2322
-
2323
-    /**
2324
-     * Return true if the given period either follows or is followed by the current one.
2325
-     *
2326
-     * @see follows()
2327
-     * @see isFollowedBy()
2328
-     *
2329
-     * @param \Carbon\CarbonPeriod|\DatePeriod|string $period
2330
-     *
2331
-     * @return bool
2332
-     */
2333
-    public function isConsecutiveWith($period, ...$arguments): bool
2334
-    {
2335
-        return $this->follows($period, ...$arguments) || $this->isFollowedBy($period, ...$arguments);
2336
-    }
2337
-
2338
-    /**
2339
-     * Update properties after removing built-in filters.
2340
-     *
2341
-     * @return void
2342
-     */
2343
-    protected function updateInternalState()
2344
-    {
2345
-        if (!$this->hasFilter(static::END_DATE_FILTER)) {
2346
-            $this->endDate = null;
2347
-        }
2348
-
2349
-        if (!$this->hasFilter(static::RECURRENCES_FILTER)) {
2350
-            $this->recurrences = null;
2351
-        }
2352
-    }
2353
-
2354
-    /**
2355
-     * Create a filter tuple from raw parameters.
2356
-     *
2357
-     * Will create an automatic filter callback for one of Carbon's is* methods.
2358
-     *
2359
-     * @param array $parameters
2360
-     *
2361
-     * @return array
2362
-     */
2363
-    protected function createFilterTuple(array $parameters)
2364
-    {
2365
-        $method = array_shift($parameters);
2366
-
2367
-        if (!$this->isCarbonPredicateMethod($method)) {
2368
-            return [$method, array_shift($parameters)];
2369
-        }
2370
-
2371
-        return [function ($date) use ($method, $parameters) {
2372
-            return ([$date, $method])(...$parameters);
2373
-        }, $method];
2374
-    }
2375
-
2376
-    /**
2377
-     * Return whether given callable is a string pointing to one of Carbon's is* methods
2378
-     * and should be automatically converted to a filter callback.
2379
-     *
2380
-     * @param callable $callable
2381
-     *
2382
-     * @return bool
2383
-     */
2384
-    protected function isCarbonPredicateMethod($callable)
2385
-    {
2386
-        return \is_string($callable) && str_starts_with($callable, 'is') &&
2387
-            (method_exists($this->dateClass, $callable) || ([$this->dateClass, 'hasMacro'])($callable));
2388
-    }
2389
-
2390
-    /**
2391
-     * Recurrences filter callback (limits number of recurrences).
2392
-     *
2393
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
2394
-     *
2395
-     * @param \Carbon\Carbon $current
2396
-     * @param int            $key
2397
-     *
2398
-     * @return bool|string
2399
-     */
2400
-    protected function filterRecurrences($current, $key)
2401
-    {
2402
-        if ($key < $this->recurrences) {
2403
-            return true;
2404
-        }
2405
-
2406
-        return static::END_ITERATION;
2407
-    }
2408
-
2409
-    /**
2410
-     * End date filter callback.
2411
-     *
2412
-     * @param \Carbon\Carbon $current
2413
-     *
2414
-     * @return bool|string
2415
-     */
2416
-    protected function filterEndDate($current)
2417
-    {
2418
-        if (!$this->isEndExcluded() && $current == $this->endDate) {
2419
-            return true;
2420
-        }
2421
-
2422
-        if ($this->dateInterval->invert ? $current > $this->endDate : $current < $this->endDate) {
2423
-            return true;
2424
-        }
2425
-
2426
-        return static::END_ITERATION;
2427
-    }
2428
-
2429
-    /**
2430
-     * End iteration filter callback.
2431
-     *
2432
-     * @return string
2433
-     */
2434
-    protected function endIteration()
2435
-    {
2436
-        return static::END_ITERATION;
2437
-    }
2438
-
2439
-    /**
2440
-     * Handle change of the parameters.
2441
-     */
2442
-    protected function handleChangedParameters()
2443
-    {
2444
-        if (($this->getOptions() & static::IMMUTABLE) && $this->dateClass === Carbon::class) {
2445
-            $this->setDateClass(CarbonImmutable::class);
2446
-        } elseif (!($this->getOptions() & static::IMMUTABLE) && $this->dateClass === CarbonImmutable::class) {
2447
-            $this->setDateClass(Carbon::class);
2448
-        }
2449
-
2450
-        $this->validationResult = null;
2451
-    }
2452
-
2453
-    /**
2454
-     * Validate current date and stop iteration when necessary.
2455
-     *
2456
-     * Returns true when current date is valid, false if it is not, or static::END_ITERATION
2457
-     * when iteration should be stopped.
2458
-     *
2459
-     * @return bool|string
2460
-     */
2461
-    protected function validateCurrentDate()
2462
-    {
2463
-        if ($this->current === null) {
2464
-            $this->rewind();
2465
-        }
2466
-
2467
-        // Check after the first rewind to avoid repeating the initial validation.
2468
-        return $this->validationResult ?? ($this->validationResult = $this->checkFilters());
2469
-    }
2470
-
2471
-    /**
2472
-     * Check whether current value and key pass all the filters.
2473
-     *
2474
-     * @return bool|string
2475
-     */
2476
-    protected function checkFilters()
2477
-    {
2478
-        $current = $this->prepareForReturn($this->current);
2479
-
2480
-        foreach ($this->filters as $tuple) {
2481
-            $result = \call_user_func(
2482
-                $tuple[0],
2483
-                $current->avoidMutation(),
2484
-                $this->key,
2485
-                $this
2486
-            );
2487
-
2488
-            if ($result === static::END_ITERATION) {
2489
-                return static::END_ITERATION;
2490
-            }
2491
-
2492
-            if (!$result) {
2493
-                return false;
2494
-            }
2495
-        }
2496
-
2497
-        return true;
2498
-    }
2499
-
2500
-    /**
2501
-     * Prepare given date to be returned to the external logic.
2502
-     *
2503
-     * @param CarbonInterface $date
2504
-     *
2505
-     * @return CarbonInterface
2506
-     */
2507
-    protected function prepareForReturn(CarbonInterface $date)
2508
-    {
2509
-        $date = ([$this->dateClass, 'make'])($date);
2510
-
2511
-        if ($this->timezone) {
2512
-            $date = $date->setTimezone($this->timezone);
2513
-        }
2514
-
2515
-        return $date;
2516
-    }
2517
-
2518
-    /**
2519
-     * Keep incrementing the current date until a valid date is found or the iteration is ended.
2520
-     *
2521
-     * @throws RuntimeException
2522
-     *
2523
-     * @return void
2524
-     */
2525
-    protected function incrementCurrentDateUntilValid()
2526
-    {
2527
-        $attempts = 0;
2528
-
2529
-        do {
2530
-            $this->current = $this->current->add($this->dateInterval);
2531
-
2532
-            $this->validationResult = null;
2533
-
2534
-            if (++$attempts > static::NEXT_MAX_ATTEMPTS) {
2535
-                throw new UnreachableException('Could not find next valid date.');
2536
-            }
2537
-        } while ($this->validateCurrentDate() === false);
2538
-    }
2539
-
2540
-    /**
2541
-     * Call given macro.
2542
-     *
2543
-     * @param string $name
2544
-     * @param array  $parameters
2545
-     *
2546
-     * @return mixed
2547
-     */
2548
-    protected function callMacro($name, $parameters)
2549
-    {
2550
-        $macro = static::$macros[$name];
2551
-
2552
-        if ($macro instanceof Closure) {
2553
-            $boundMacro = @$macro->bindTo($this, static::class) ?: @$macro->bindTo(null, static::class);
2554
-
2555
-            return ($boundMacro ?: $macro)(...$parameters);
2556
-        }
2557
-
2558
-        return $macro(...$parameters);
2559
-    }
2560
-
2561
-    /**
2562
-     * Return the Carbon instance passed through, a now instance in the same timezone
2563
-     * if null given or parse the input if string given.
2564
-     *
2565
-     * @param \Carbon\Carbon|\Carbon\CarbonPeriod|\Carbon\CarbonInterval|\DateInterval|\DatePeriod|\DateTimeInterface|string|null $date
2566
-     *
2567
-     * @return \Carbon\CarbonInterface
2568
-     */
2569
-    protected function resolveCarbon($date = null)
2570
-    {
2571
-        return $this->getStartDate()->nowWithSameTz()->carbonize($date);
2572
-    }
2573
-
2574
-    /**
2575
-     * Resolve passed arguments or DatePeriod to a CarbonPeriod object.
2576
-     *
2577
-     * @param mixed $period
2578
-     * @param mixed ...$arguments
2579
-     *
2580
-     * @return static
2581
-     */
2582
-    protected function resolveCarbonPeriod($period, ...$arguments)
2583
-    {
2584
-        if ($period instanceof self) {
2585
-            return $period;
2586
-        }
2587
-
2588
-        return $period instanceof DatePeriod
2589
-            ? static::instance($period)
2590
-            : static::create($period, ...$arguments);
2591
-    }
2592
-
2593
-    private function orderCouple($first, $second): array
2594
-    {
2595
-        return $first > $second ? [$second, $first] : [$first, $second];
2596
-    }
2597
-
2598
-    private function makeDateTime($value): ?DateTimeInterface
2599
-    {
2600
-        if ($value instanceof DateTimeInterface) {
2601
-            return $value;
2602
-        }
2603
-
2604
-        if (\is_string($value)) {
2605
-            $value = trim($value);
2606
-
2607
-            if (!preg_match('/^P[\dT]/', $value) &&
2608
-                !preg_match('/^R\d/', $value) &&
2609
-                preg_match('/[a-z\d]/i', $value)
2610
-            ) {
2611
-                return Carbon::parse($value, $this->tzName);
2612
-            }
2613
-        }
2614
-
2615
-        return null;
2616
-    }
2617
-
2618
-    private function isInfiniteDate($date): bool
2619
-    {
2620
-        return $date instanceof CarbonInterface && ($date->isEndOfTime() || $date->isStartOfTime());
2621
-    }
2622
-
2623
-    private function rawDate($date): ?DateTimeInterface
2624
-    {
2625
-        if ($date === false || $date === null) {
2626
-            return null;
2627
-        }
2628
-
2629
-        if ($date instanceof CarbonInterface) {
2630
-            return $date->isMutable()
2631
-                ? $date->toDateTime()
2632
-                : $date->toDateTimeImmutable();
2633
-        }
2634
-
2635
-        if (\in_array(\get_class($date), [DateTime::class, DateTimeImmutable::class], true)) {
2636
-            return $date;
2637
-        }
2638
-
2639
-        $class = $date instanceof DateTime ? DateTime::class : DateTimeImmutable::class;
2640
-
2641
-        return new $class($date->format('Y-m-d H:i:s.u'), $date->getTimezone());
2642
-    }
173
+	use IntervalRounding;
174
+	use Mixin {
175
+		Mixin::mixin as baseMixin;
176
+	}
177
+	use Options;
178
+
179
+	/**
180
+	 * Built-in filter for limit by recurrences.
181
+	 *
182
+	 * @var callable
183
+	 */
184
+	public const RECURRENCES_FILTER = [self::class, 'filterRecurrences'];
185
+
186
+	/**
187
+	 * Built-in filter for limit to an end.
188
+	 *
189
+	 * @var callable
190
+	 */
191
+	public const END_DATE_FILTER = [self::class, 'filterEndDate'];
192
+
193
+	/**
194
+	 * Special value which can be returned by filters to end iteration. Also a filter.
195
+	 *
196
+	 * @var callable
197
+	 */
198
+	public const END_ITERATION = [self::class, 'endIteration'];
199
+
200
+	/**
201
+	 * Exclude start date from iteration.
202
+	 *
203
+	 * @var int
204
+	 */
205
+	public const EXCLUDE_START_DATE = 1;
206
+
207
+	/**
208
+	 * Exclude end date from iteration.
209
+	 *
210
+	 * @var int
211
+	 */
212
+	public const EXCLUDE_END_DATE = 2;
213
+
214
+	/**
215
+	 * Yield CarbonImmutable instances.
216
+	 *
217
+	 * @var int
218
+	 */
219
+	public const IMMUTABLE = 4;
220
+
221
+	/**
222
+	 * Number of maximum attempts before giving up on finding next valid date.
223
+	 *
224
+	 * @var int
225
+	 */
226
+	public const NEXT_MAX_ATTEMPTS = 1000;
227
+
228
+	/**
229
+	 * Number of maximum attempts before giving up on finding end date.
230
+	 *
231
+	 * @var int
232
+	 */
233
+	public const END_MAX_ATTEMPTS = 10000;
234
+
235
+	/**
236
+	 * The registered macros.
237
+	 *
238
+	 * @var array
239
+	 */
240
+	protected static $macros = [];
241
+
242
+	/**
243
+	 * Date class of iteration items.
244
+	 *
245
+	 * @var string
246
+	 */
247
+	protected $dateClass = Carbon::class;
248
+
249
+	/**
250
+	 * Underlying date interval instance. Always present, one day by default.
251
+	 *
252
+	 * @var CarbonInterval
253
+	 */
254
+	protected $dateInterval;
255
+
256
+	/**
257
+	 * Whether current date interval was set by default.
258
+	 *
259
+	 * @var bool
260
+	 */
261
+	protected $isDefaultInterval;
262
+
263
+	/**
264
+	 * The filters stack.
265
+	 *
266
+	 * @var array
267
+	 */
268
+	protected $filters = [];
269
+
270
+	/**
271
+	 * Period start date. Applied on rewind. Always present, now by default.
272
+	 *
273
+	 * @var CarbonInterface
274
+	 */
275
+	protected $startDate;
276
+
277
+	/**
278
+	 * Period end date. For inverted interval should be before the start date. Applied via a filter.
279
+	 *
280
+	 * @var CarbonInterface|null
281
+	 */
282
+	protected $endDate;
283
+
284
+	/**
285
+	 * Limit for number of recurrences. Applied via a filter.
286
+	 *
287
+	 * @var int|null
288
+	 */
289
+	protected $recurrences;
290
+
291
+	/**
292
+	 * Iteration options.
293
+	 *
294
+	 * @var int
295
+	 */
296
+	protected $options;
297
+
298
+	/**
299
+	 * Index of current date. Always sequential, even if some dates are skipped by filters.
300
+	 * Equal to null only before the first iteration.
301
+	 *
302
+	 * @var int
303
+	 */
304
+	protected $key;
305
+
306
+	/**
307
+	 * Current date. May temporarily hold unaccepted value when looking for a next valid date.
308
+	 * Equal to null only before the first iteration.
309
+	 *
310
+	 * @var CarbonInterface
311
+	 */
312
+	protected $current;
313
+
314
+	/**
315
+	 * Timezone of current date. Taken from the start date.
316
+	 *
317
+	 * @var \DateTimeZone|null
318
+	 */
319
+	protected $timezone;
320
+
321
+	/**
322
+	 * The cached validation result for current date.
323
+	 *
324
+	 * @var bool|string|null
325
+	 */
326
+	protected $validationResult;
327
+
328
+	/**
329
+	 * Timezone handler for settings() method.
330
+	 *
331
+	 * @var mixed
332
+	 */
333
+	protected $tzName;
334
+
335
+	/**
336
+	 * Make a CarbonPeriod instance from given variable if possible.
337
+	 *
338
+	 * @param mixed $var
339
+	 *
340
+	 * @return static|null
341
+	 */
342
+	public static function make($var)
343
+	{
344
+		try {
345
+			return static::instance($var);
346
+		} catch (NotAPeriodException $e) {
347
+			return static::create($var);
348
+		}
349
+	}
350
+
351
+	/**
352
+	 * Create a new instance from a DatePeriod or CarbonPeriod object.
353
+	 *
354
+	 * @param CarbonPeriod|DatePeriod $period
355
+	 *
356
+	 * @return static
357
+	 */
358
+	public static function instance($period)
359
+	{
360
+		if ($period instanceof static) {
361
+			return $period->copy();
362
+		}
363
+
364
+		if ($period instanceof self) {
365
+			return new static(
366
+				$period->getStartDate(),
367
+				$period->getEndDate() ?: $period->getRecurrences(),
368
+				$period->getDateInterval(),
369
+				$period->getOptions()
370
+			);
371
+		}
372
+
373
+		if ($period instanceof DatePeriod) {
374
+			return new static(
375
+				$period->start,
376
+				$period->end ?: ($period->recurrences - 1),
377
+				$period->interval,
378
+				$period->include_start_date ? 0 : static::EXCLUDE_START_DATE
379
+			);
380
+		}
381
+
382
+		$class = static::class;
383
+		$type = \gettype($period);
384
+
385
+		throw new NotAPeriodException(
386
+			'Argument 1 passed to '.$class.'::'.__METHOD__.'() '.
387
+			'must be an instance of DatePeriod or '.$class.', '.
388
+			($type === 'object' ? 'instance of '.\get_class($period) : $type).' given.'
389
+		);
390
+	}
391
+
392
+	/**
393
+	 * Create a new instance.
394
+	 *
395
+	 * @return static
396
+	 */
397
+	public static function create(...$params)
398
+	{
399
+		return static::createFromArray($params);
400
+	}
401
+
402
+	/**
403
+	 * Create a new instance from an array of parameters.
404
+	 *
405
+	 * @param array $params
406
+	 *
407
+	 * @return static
408
+	 */
409
+	public static function createFromArray(array $params)
410
+	{
411
+		return new static(...$params);
412
+	}
413
+
414
+	/**
415
+	 * Create CarbonPeriod from ISO 8601 string.
416
+	 *
417
+	 * @param string   $iso
418
+	 * @param int|null $options
419
+	 *
420
+	 * @return static
421
+	 */
422
+	public static function createFromIso($iso, $options = null)
423
+	{
424
+		$params = static::parseIso8601($iso);
425
+
426
+		$instance = static::createFromArray($params);
427
+
428
+		if ($options !== null) {
429
+			$instance->setOptions($options);
430
+		}
431
+
432
+		return $instance;
433
+	}
434
+
435
+	/**
436
+	 * Return whether given interval contains non zero value of any time unit.
437
+	 *
438
+	 * @param \DateInterval $interval
439
+	 *
440
+	 * @return bool
441
+	 */
442
+	protected static function intervalHasTime(DateInterval $interval)
443
+	{
444
+		return $interval->h || $interval->i || $interval->s || $interval->f;
445
+	}
446
+
447
+	/**
448
+	 * Return whether given variable is an ISO 8601 specification.
449
+	 *
450
+	 * Note: Check is very basic, as actual validation will be done later when parsing.
451
+	 * We just want to ensure that variable is not any other type of a valid parameter.
452
+	 *
453
+	 * @param mixed $var
454
+	 *
455
+	 * @return bool
456
+	 */
457
+	protected static function isIso8601($var)
458
+	{
459
+		if (!\is_string($var)) {
460
+			return false;
461
+		}
462
+
463
+		// Match slash but not within a timezone name.
464
+		$part = '[a-z]+(?:[_-][a-z]+)*';
465
+
466
+		preg_match("#\b$part/$part\b|(/)#i", $var, $match);
467
+
468
+		return isset($match[1]);
469
+	}
470
+
471
+	/**
472
+	 * Parse given ISO 8601 string into an array of arguments.
473
+	 *
474
+	 * @SuppressWarnings(PHPMD.ElseExpression)
475
+	 *
476
+	 * @param string $iso
477
+	 *
478
+	 * @return array
479
+	 */
480
+	protected static function parseIso8601($iso)
481
+	{
482
+		$result = [];
483
+
484
+		$interval = null;
485
+		$start = null;
486
+		$end = null;
487
+
488
+		foreach (explode('/', $iso) as $key => $part) {
489
+			if ($key === 0 && preg_match('/^R(\d*|INF)$/', $part, $match)) {
490
+				$parsed = \strlen($match[1]) ? (($match[1] !== 'INF') ? (int) $match[1] : INF) : null;
491
+			} elseif ($interval === null && $parsed = CarbonInterval::make($part)) {
492
+				$interval = $part;
493
+			} elseif ($start === null && $parsed = Carbon::make($part)) {
494
+				$start = $part;
495
+			} elseif ($end === null && $parsed = Carbon::make(static::addMissingParts($start ?? '', $part))) {
496
+				$end = $part;
497
+			} else {
498
+				throw new InvalidPeriodParameterException("Invalid ISO 8601 specification: $iso.");
499
+			}
500
+
501
+			$result[] = $parsed;
502
+		}
503
+
504
+		return $result;
505
+	}
506
+
507
+	/**
508
+	 * Add missing parts of the target date from the soure date.
509
+	 *
510
+	 * @param string $source
511
+	 * @param string $target
512
+	 *
513
+	 * @return string
514
+	 */
515
+	protected static function addMissingParts($source, $target)
516
+	{
517
+		$pattern = '/'.preg_replace('/\d+/', '[0-9]+', preg_quote($target, '/')).'$/';
518
+
519
+		$result = preg_replace($pattern, $target, $source, 1, $count);
520
+
521
+		return $count ? $result : $target;
522
+	}
523
+
524
+	/**
525
+	 * Register a custom macro.
526
+	 *
527
+	 * @example
528
+	 * ```
529
+	 * CarbonPeriod::macro('middle', function () {
530
+	 *   return $this->getStartDate()->average($this->getEndDate());
531
+	 * });
532
+	 * echo CarbonPeriod::since('2011-05-12')->until('2011-06-03')->middle();
533
+	 * ```
534
+	 *
535
+	 * @param string          $name
536
+	 * @param object|callable $macro
537
+	 *
538
+	 * @return void
539
+	 */
540
+	public static function macro($name, $macro)
541
+	{
542
+		static::$macros[$name] = $macro;
543
+	}
544
+
545
+	/**
546
+	 * Register macros from a mixin object.
547
+	 *
548
+	 * @example
549
+	 * ```
550
+	 * CarbonPeriod::mixin(new class {
551
+	 *   public function addDays() {
552
+	 *     return function ($count = 1) {
553
+	 *       return $this->setStartDate(
554
+	 *         $this->getStartDate()->addDays($count)
555
+	 *       )->setEndDate(
556
+	 *         $this->getEndDate()->addDays($count)
557
+	 *       );
558
+	 *     };
559
+	 *   }
560
+	 *   public function subDays() {
561
+	 *     return function ($count = 1) {
562
+	 *       return $this->setStartDate(
563
+	 *         $this->getStartDate()->subDays($count)
564
+	 *       )->setEndDate(
565
+	 *         $this->getEndDate()->subDays($count)
566
+	 *       );
567
+	 *     };
568
+	 *   }
569
+	 * });
570
+	 * echo CarbonPeriod::create('2000-01-01', '2000-02-01')->addDays(5)->subDays(3);
571
+	 * ```
572
+	 *
573
+	 * @param object|string $mixin
574
+	 *
575
+	 * @throws ReflectionException
576
+	 *
577
+	 * @return void
578
+	 */
579
+	public static function mixin($mixin)
580
+	{
581
+		static::baseMixin($mixin);
582
+	}
583
+
584
+	/**
585
+	 * Check if macro is registered.
586
+	 *
587
+	 * @param string $name
588
+	 *
589
+	 * @return bool
590
+	 */
591
+	public static function hasMacro($name)
592
+	{
593
+		return isset(static::$macros[$name]);
594
+	}
595
+
596
+	/**
597
+	 * Provide static proxy for instance aliases.
598
+	 *
599
+	 * @param string $method
600
+	 * @param array  $parameters
601
+	 *
602
+	 * @return mixed
603
+	 */
604
+	public static function __callStatic($method, $parameters)
605
+	{
606
+		$date = new static();
607
+
608
+		if (static::hasMacro($method)) {
609
+			return static::bindMacroContext(null, function () use (&$method, &$parameters, &$date) {
610
+				return $date->callMacro($method, $parameters);
611
+			});
612
+		}
613
+
614
+		return $date->$method(...$parameters);
615
+	}
616
+
617
+	/**
618
+	 * CarbonPeriod constructor.
619
+	 *
620
+	 * @SuppressWarnings(PHPMD.ElseExpression)
621
+	 *
622
+	 * @throws InvalidArgumentException
623
+	 */
624
+	public function __construct(...$arguments)
625
+	{
626
+		// Parse and assign arguments one by one. First argument may be an ISO 8601 spec,
627
+		// which will be first parsed into parts and then processed the same way.
628
+
629
+		$argumentsCount = \count($arguments);
630
+
631
+		if ($argumentsCount && static::isIso8601($iso = $arguments[0])) {
632
+			array_splice($arguments, 0, 1, static::parseIso8601($iso));
633
+		}
634
+
635
+		if ($argumentsCount === 1) {
636
+			if ($arguments[0] instanceof DatePeriod) {
637
+				$arguments = [
638
+					$arguments[0]->start,
639
+					$arguments[0]->end ?: ($arguments[0]->recurrences - 1),
640
+					$arguments[0]->interval,
641
+					$arguments[0]->include_start_date ? 0 : static::EXCLUDE_START_DATE,
642
+				];
643
+			} elseif ($arguments[0] instanceof self) {
644
+				$arguments = [
645
+					$arguments[0]->getStartDate(),
646
+					$arguments[0]->getEndDate() ?: $arguments[0]->getRecurrences(),
647
+					$arguments[0]->getDateInterval(),
648
+					$arguments[0]->getOptions(),
649
+				];
650
+			}
651
+		}
652
+
653
+		foreach ($arguments as $argument) {
654
+			$parsedDate = null;
655
+
656
+			if ($argument instanceof DateTimeZone) {
657
+				$this->setTimezone($argument);
658
+			} elseif ($this->dateInterval === null &&
659
+				(
660
+					(\is_string($argument) && preg_match(
661
+						'/^(-?\d(\d(?![\/-])|[^\d\/-]([\/-])?)*|P[T\d].*|(?:\h*\d+(?:\.\d+)?\h*[a-z]+)+)$/i',
662
+						$argument
663
+					)) ||
664
+					$argument instanceof DateInterval ||
665
+					$argument instanceof Closure
666
+				) &&
667
+				$parsedInterval = @CarbonInterval::make($argument)
668
+			) {
669
+				$this->setDateInterval($parsedInterval);
670
+			} elseif ($this->startDate === null && $parsedDate = $this->makeDateTime($argument)) {
671
+				$this->setStartDate($parsedDate);
672
+			} elseif ($this->endDate === null && ($parsedDate = $parsedDate ?? $this->makeDateTime($argument))) {
673
+				$this->setEndDate($parsedDate);
674
+			} elseif ($this->recurrences === null && $this->endDate === null && is_numeric($argument)) {
675
+				$this->setRecurrences($argument);
676
+			} elseif ($this->options === null && (\is_int($argument) || $argument === null)) {
677
+				$this->setOptions($argument);
678
+			} else {
679
+				throw new InvalidPeriodParameterException('Invalid constructor parameters.');
680
+			}
681
+		}
682
+
683
+		if ($this->startDate === null) {
684
+			$this->setStartDate(Carbon::now());
685
+		}
686
+
687
+		if ($this->dateInterval === null) {
688
+			$this->setDateInterval(CarbonInterval::day());
689
+
690
+			$this->isDefaultInterval = true;
691
+		}
692
+
693
+		if ($this->options === null) {
694
+			$this->setOptions(0);
695
+		}
696
+	}
697
+
698
+	/**
699
+	 * Get a copy of the instance.
700
+	 *
701
+	 * @return static
702
+	 */
703
+	public function copy()
704
+	{
705
+		return clone $this;
706
+	}
707
+
708
+	/**
709
+	 * Get the getter for a property allowing both `DatePeriod` snakeCase and camelCase names.
710
+	 *
711
+	 * @param string $name
712
+	 *
713
+	 * @return callable|null
714
+	 */
715
+	protected function getGetter(string $name)
716
+	{
717
+		switch (strtolower(preg_replace('/[A-Z]/', '_$0', $name))) {
718
+			case 'start':
719
+			case 'start_date':
720
+				return [$this, 'getStartDate'];
721
+			case 'end':
722
+			case 'end_date':
723
+				return [$this, 'getEndDate'];
724
+			case 'interval':
725
+			case 'date_interval':
726
+				return [$this, 'getDateInterval'];
727
+			case 'recurrences':
728
+				return [$this, 'getRecurrences'];
729
+			case 'include_start_date':
730
+				return [$this, 'isStartIncluded'];
731
+			case 'include_end_date':
732
+				return [$this, 'isEndIncluded'];
733
+			case 'current':
734
+				return [$this, 'current'];
735
+			default:
736
+				return null;
737
+		}
738
+	}
739
+
740
+	/**
741
+	 * Get a property allowing both `DatePeriod` snakeCase and camelCase names.
742
+	 *
743
+	 * @param string $name
744
+	 *
745
+	 * @return bool|CarbonInterface|CarbonInterval|int|null
746
+	 */
747
+	public function get(string $name)
748
+	{
749
+		$getter = $this->getGetter($name);
750
+
751
+		if ($getter) {
752
+			return $getter();
753
+		}
754
+
755
+		throw new UnknownGetterException($name);
756
+	}
757
+
758
+	/**
759
+	 * Get a property allowing both `DatePeriod` snakeCase and camelCase names.
760
+	 *
761
+	 * @param string $name
762
+	 *
763
+	 * @return bool|CarbonInterface|CarbonInterval|int|null
764
+	 */
765
+	public function __get(string $name)
766
+	{
767
+		return $this->get($name);
768
+	}
769
+
770
+	/**
771
+	 * Check if an attribute exists on the object
772
+	 *
773
+	 * @param string $name
774
+	 *
775
+	 * @return bool
776
+	 */
777
+	public function __isset(string $name): bool
778
+	{
779
+		return $this->getGetter($name) !== null;
780
+	}
781
+
782
+	/**
783
+	 * @alias copy
784
+	 *
785
+	 * Get a copy of the instance.
786
+	 *
787
+	 * @return static
788
+	 */
789
+	public function clone()
790
+	{
791
+		return clone $this;
792
+	}
793
+
794
+	/**
795
+	 * Set the iteration item class.
796
+	 *
797
+	 * @param string $dateClass
798
+	 *
799
+	 * @return $this
800
+	 */
801
+	public function setDateClass(string $dateClass)
802
+	{
803
+		if (!is_a($dateClass, CarbonInterface::class, true)) {
804
+			throw new NotACarbonClassException($dateClass);
805
+		}
806
+
807
+		$this->dateClass = $dateClass;
808
+
809
+		if (is_a($dateClass, Carbon::class, true)) {
810
+			$this->toggleOptions(static::IMMUTABLE, false);
811
+		} elseif (is_a($dateClass, CarbonImmutable::class, true)) {
812
+			$this->toggleOptions(static::IMMUTABLE, true);
813
+		}
814
+
815
+		return $this;
816
+	}
817
+
818
+	/**
819
+	 * Returns iteration item date class.
820
+	 *
821
+	 * @return string
822
+	 */
823
+	public function getDateClass(): string
824
+	{
825
+		return $this->dateClass;
826
+	}
827
+
828
+	/**
829
+	 * Change the period date interval.
830
+	 *
831
+	 * @param DateInterval|string $interval
832
+	 *
833
+	 * @throws InvalidIntervalException
834
+	 *
835
+	 * @return $this
836
+	 */
837
+	public function setDateInterval($interval)
838
+	{
839
+		if (!$interval = CarbonInterval::make($interval)) {
840
+			throw new InvalidIntervalException('Invalid interval.');
841
+		}
842
+
843
+		if ($interval->spec() === 'PT0S' && !$interval->f && !$interval->getStep()) {
844
+			throw new InvalidIntervalException('Empty interval is not accepted.');
845
+		}
846
+
847
+		$this->dateInterval = $interval;
848
+
849
+		$this->isDefaultInterval = false;
850
+
851
+		$this->handleChangedParameters();
852
+
853
+		return $this;
854
+	}
855
+
856
+	/**
857
+	 * Invert the period date interval.
858
+	 *
859
+	 * @return $this
860
+	 */
861
+	public function invertDateInterval()
862
+	{
863
+		$interval = $this->dateInterval->invert();
864
+
865
+		return $this->setDateInterval($interval);
866
+	}
867
+
868
+	/**
869
+	 * Set start and end date.
870
+	 *
871
+	 * @param DateTime|DateTimeInterface|string      $start
872
+	 * @param DateTime|DateTimeInterface|string|null $end
873
+	 *
874
+	 * @return $this
875
+	 */
876
+	public function setDates($start, $end)
877
+	{
878
+		$this->setStartDate($start);
879
+		$this->setEndDate($end);
880
+
881
+		return $this;
882
+	}
883
+
884
+	/**
885
+	 * Change the period options.
886
+	 *
887
+	 * @param int|null $options
888
+	 *
889
+	 * @throws InvalidArgumentException
890
+	 *
891
+	 * @return $this
892
+	 */
893
+	public function setOptions($options)
894
+	{
895
+		if (!\is_int($options) && $options !== null) {
896
+			throw new InvalidPeriodParameterException('Invalid options.');
897
+		}
898
+
899
+		$this->options = $options ?: 0;
900
+
901
+		$this->handleChangedParameters();
902
+
903
+		return $this;
904
+	}
905
+
906
+	/**
907
+	 * Get the period options.
908
+	 *
909
+	 * @return int
910
+	 */
911
+	public function getOptions()
912
+	{
913
+		return $this->options;
914
+	}
915
+
916
+	/**
917
+	 * Toggle given options on or off.
918
+	 *
919
+	 * @param int       $options
920
+	 * @param bool|null $state
921
+	 *
922
+	 * @throws \InvalidArgumentException
923
+	 *
924
+	 * @return $this
925
+	 */
926
+	public function toggleOptions($options, $state = null)
927
+	{
928
+		if ($state === null) {
929
+			$state = ($this->options & $options) !== $options;
930
+		}
931
+
932
+		return $this->setOptions(
933
+			$state ?
934
+			$this->options | $options :
935
+			$this->options & ~$options
936
+		);
937
+	}
938
+
939
+	/**
940
+	 * Toggle EXCLUDE_START_DATE option.
941
+	 *
942
+	 * @param bool $state
943
+	 *
944
+	 * @return $this
945
+	 */
946
+	public function excludeStartDate($state = true)
947
+	{
948
+		return $this->toggleOptions(static::EXCLUDE_START_DATE, $state);
949
+	}
950
+
951
+	/**
952
+	 * Toggle EXCLUDE_END_DATE option.
953
+	 *
954
+	 * @param bool $state
955
+	 *
956
+	 * @return $this
957
+	 */
958
+	public function excludeEndDate($state = true)
959
+	{
960
+		return $this->toggleOptions(static::EXCLUDE_END_DATE, $state);
961
+	}
962
+
963
+	/**
964
+	 * Get the underlying date interval.
965
+	 *
966
+	 * @return CarbonInterval
967
+	 */
968
+	public function getDateInterval()
969
+	{
970
+		return $this->dateInterval->copy();
971
+	}
972
+
973
+	/**
974
+	 * Get start date of the period.
975
+	 *
976
+	 * @param string|null $rounding Optional rounding 'floor', 'ceil', 'round' using the period interval.
977
+	 *
978
+	 * @return CarbonInterface
979
+	 */
980
+	public function getStartDate(string $rounding = null)
981
+	{
982
+		$date = $this->startDate->avoidMutation();
983
+
984
+		return $rounding ? $date->round($this->getDateInterval(), $rounding) : $date;
985
+	}
986
+
987
+	/**
988
+	 * Get end date of the period.
989
+	 *
990
+	 * @param string|null $rounding Optional rounding 'floor', 'ceil', 'round' using the period interval.
991
+	 *
992
+	 * @return CarbonInterface|null
993
+	 */
994
+	public function getEndDate(string $rounding = null)
995
+	{
996
+		if (!$this->endDate) {
997
+			return null;
998
+		}
999
+
1000
+		$date = $this->endDate->avoidMutation();
1001
+
1002
+		return $rounding ? $date->round($this->getDateInterval(), $rounding) : $date;
1003
+	}
1004
+
1005
+	/**
1006
+	 * Get number of recurrences.
1007
+	 *
1008
+	 * @return int|float|null
1009
+	 */
1010
+	public function getRecurrences()
1011
+	{
1012
+		return $this->recurrences;
1013
+	}
1014
+
1015
+	/**
1016
+	 * Returns true if the start date should be excluded.
1017
+	 *
1018
+	 * @return bool
1019
+	 */
1020
+	public function isStartExcluded()
1021
+	{
1022
+		return ($this->options & static::EXCLUDE_START_DATE) !== 0;
1023
+	}
1024
+
1025
+	/**
1026
+	 * Returns true if the end date should be excluded.
1027
+	 *
1028
+	 * @return bool
1029
+	 */
1030
+	public function isEndExcluded()
1031
+	{
1032
+		return ($this->options & static::EXCLUDE_END_DATE) !== 0;
1033
+	}
1034
+
1035
+	/**
1036
+	 * Returns true if the start date should be included.
1037
+	 *
1038
+	 * @return bool
1039
+	 */
1040
+	public function isStartIncluded()
1041
+	{
1042
+		return !$this->isStartExcluded();
1043
+	}
1044
+
1045
+	/**
1046
+	 * Returns true if the end date should be included.
1047
+	 *
1048
+	 * @return bool
1049
+	 */
1050
+	public function isEndIncluded()
1051
+	{
1052
+		return !$this->isEndExcluded();
1053
+	}
1054
+
1055
+	/**
1056
+	 * Return the start if it's included by option, else return the start + 1 period interval.
1057
+	 *
1058
+	 * @return CarbonInterface
1059
+	 */
1060
+	public function getIncludedStartDate()
1061
+	{
1062
+		$start = $this->getStartDate();
1063
+
1064
+		if ($this->isStartExcluded()) {
1065
+			return $start->add($this->getDateInterval());
1066
+		}
1067
+
1068
+		return $start;
1069
+	}
1070
+
1071
+	/**
1072
+	 * Return the end if it's included by option, else return the end - 1 period interval.
1073
+	 * Warning: if the period has no fixed end, this method will iterate the period to calculate it.
1074
+	 *
1075
+	 * @return CarbonInterface
1076
+	 */
1077
+	public function getIncludedEndDate()
1078
+	{
1079
+		$end = $this->getEndDate();
1080
+
1081
+		if (!$end) {
1082
+			return $this->calculateEnd();
1083
+		}
1084
+
1085
+		if ($this->isEndExcluded()) {
1086
+			return $end->sub($this->getDateInterval());
1087
+		}
1088
+
1089
+		return $end;
1090
+	}
1091
+
1092
+	/**
1093
+	 * Add a filter to the stack.
1094
+	 *
1095
+	 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
1096
+	 *
1097
+	 * @param callable $callback
1098
+	 * @param string   $name
1099
+	 *
1100
+	 * @return $this
1101
+	 */
1102
+	public function addFilter($callback, $name = null)
1103
+	{
1104
+		$tuple = $this->createFilterTuple(\func_get_args());
1105
+
1106
+		$this->filters[] = $tuple;
1107
+
1108
+		$this->handleChangedParameters();
1109
+
1110
+		return $this;
1111
+	}
1112
+
1113
+	/**
1114
+	 * Prepend a filter to the stack.
1115
+	 *
1116
+	 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
1117
+	 *
1118
+	 * @param callable $callback
1119
+	 * @param string   $name
1120
+	 *
1121
+	 * @return $this
1122
+	 */
1123
+	public function prependFilter($callback, $name = null)
1124
+	{
1125
+		$tuple = $this->createFilterTuple(\func_get_args());
1126
+
1127
+		array_unshift($this->filters, $tuple);
1128
+
1129
+		$this->handleChangedParameters();
1130
+
1131
+		return $this;
1132
+	}
1133
+
1134
+	/**
1135
+	 * Remove a filter by instance or name.
1136
+	 *
1137
+	 * @param callable|string $filter
1138
+	 *
1139
+	 * @return $this
1140
+	 */
1141
+	public function removeFilter($filter)
1142
+	{
1143
+		$key = \is_callable($filter) ? 0 : 1;
1144
+
1145
+		$this->filters = array_values(array_filter(
1146
+			$this->filters,
1147
+			function ($tuple) use ($key, $filter) {
1148
+				return $tuple[$key] !== $filter;
1149
+			}
1150
+		));
1151
+
1152
+		$this->updateInternalState();
1153
+
1154
+		$this->handleChangedParameters();
1155
+
1156
+		return $this;
1157
+	}
1158
+
1159
+	/**
1160
+	 * Return whether given instance or name is in the filter stack.
1161
+	 *
1162
+	 * @param callable|string $filter
1163
+	 *
1164
+	 * @return bool
1165
+	 */
1166
+	public function hasFilter($filter)
1167
+	{
1168
+		$key = \is_callable($filter) ? 0 : 1;
1169
+
1170
+		foreach ($this->filters as $tuple) {
1171
+			if ($tuple[$key] === $filter) {
1172
+				return true;
1173
+			}
1174
+		}
1175
+
1176
+		return false;
1177
+	}
1178
+
1179
+	/**
1180
+	 * Get filters stack.
1181
+	 *
1182
+	 * @return array
1183
+	 */
1184
+	public function getFilters()
1185
+	{
1186
+		return $this->filters;
1187
+	}
1188
+
1189
+	/**
1190
+	 * Set filters stack.
1191
+	 *
1192
+	 * @param array $filters
1193
+	 *
1194
+	 * @return $this
1195
+	 */
1196
+	public function setFilters(array $filters)
1197
+	{
1198
+		$this->filters = $filters;
1199
+
1200
+		$this->updateInternalState();
1201
+
1202
+		$this->handleChangedParameters();
1203
+
1204
+		return $this;
1205
+	}
1206
+
1207
+	/**
1208
+	 * Reset filters stack.
1209
+	 *
1210
+	 * @return $this
1211
+	 */
1212
+	public function resetFilters()
1213
+	{
1214
+		$this->filters = [];
1215
+
1216
+		if ($this->endDate !== null) {
1217
+			$this->filters[] = [static::END_DATE_FILTER, null];
1218
+		}
1219
+
1220
+		if ($this->recurrences !== null) {
1221
+			$this->filters[] = [static::RECURRENCES_FILTER, null];
1222
+		}
1223
+
1224
+		$this->handleChangedParameters();
1225
+
1226
+		return $this;
1227
+	}
1228
+
1229
+	/**
1230
+	 * Add a recurrences filter (set maximum number of recurrences).
1231
+	 *
1232
+	 * @param int|float|null $recurrences
1233
+	 *
1234
+	 * @throws InvalidArgumentException
1235
+	 *
1236
+	 * @return $this
1237
+	 */
1238
+	public function setRecurrences($recurrences)
1239
+	{
1240
+		if ((!is_numeric($recurrences) && $recurrences !== null) || $recurrences < 0) {
1241
+			throw new InvalidPeriodParameterException('Invalid number of recurrences.');
1242
+		}
1243
+
1244
+		if ($recurrences === null) {
1245
+			return $this->removeFilter(static::RECURRENCES_FILTER);
1246
+		}
1247
+
1248
+		$this->recurrences = $recurrences === INF ? INF : (int) $recurrences;
1249
+
1250
+		if (!$this->hasFilter(static::RECURRENCES_FILTER)) {
1251
+			return $this->addFilter(static::RECURRENCES_FILTER);
1252
+		}
1253
+
1254
+		$this->handleChangedParameters();
1255
+
1256
+		return $this;
1257
+	}
1258
+
1259
+	/**
1260
+	 * Change the period start date.
1261
+	 *
1262
+	 * @param DateTime|DateTimeInterface|string $date
1263
+	 * @param bool|null                         $inclusive
1264
+	 *
1265
+	 * @throws InvalidPeriodDateException
1266
+	 *
1267
+	 * @return $this
1268
+	 */
1269
+	public function setStartDate($date, $inclusive = null)
1270
+	{
1271
+		if (!$this->isInfiniteDate($date) && !($date = ([$this->dateClass, 'make'])($date))) {
1272
+			throw new InvalidPeriodDateException('Invalid start date.');
1273
+		}
1274
+
1275
+		$this->startDate = $date;
1276
+
1277
+		if ($inclusive !== null) {
1278
+			$this->toggleOptions(static::EXCLUDE_START_DATE, !$inclusive);
1279
+		}
1280
+
1281
+		return $this;
1282
+	}
1283
+
1284
+	/**
1285
+	 * Change the period end date.
1286
+	 *
1287
+	 * @param DateTime|DateTimeInterface|string|null $date
1288
+	 * @param bool|null                              $inclusive
1289
+	 *
1290
+	 * @throws \InvalidArgumentException
1291
+	 *
1292
+	 * @return $this
1293
+	 */
1294
+	public function setEndDate($date, $inclusive = null)
1295
+	{
1296
+		if ($date !== null && !$this->isInfiniteDate($date) && !$date = ([$this->dateClass, 'make'])($date)) {
1297
+			throw new InvalidPeriodDateException('Invalid end date.');
1298
+		}
1299
+
1300
+		if (!$date) {
1301
+			return $this->removeFilter(static::END_DATE_FILTER);
1302
+		}
1303
+
1304
+		$this->endDate = $date;
1305
+
1306
+		if ($inclusive !== null) {
1307
+			$this->toggleOptions(static::EXCLUDE_END_DATE, !$inclusive);
1308
+		}
1309
+
1310
+		if (!$this->hasFilter(static::END_DATE_FILTER)) {
1311
+			return $this->addFilter(static::END_DATE_FILTER);
1312
+		}
1313
+
1314
+		$this->handleChangedParameters();
1315
+
1316
+		return $this;
1317
+	}
1318
+
1319
+	/**
1320
+	 * Check if the current position is valid.
1321
+	 *
1322
+	 * @return bool
1323
+	 */
1324
+	#[ReturnTypeWillChange]
1325
+	public function valid()
1326
+	{
1327
+		return $this->validateCurrentDate() === true;
1328
+	}
1329
+
1330
+	/**
1331
+	 * Return the current key.
1332
+	 *
1333
+	 * @return int|null
1334
+	 */
1335
+	#[ReturnTypeWillChange]
1336
+	public function key()
1337
+	{
1338
+		return $this->valid()
1339
+			? $this->key
1340
+			: null;
1341
+	}
1342
+
1343
+	/**
1344
+	 * Return the current date.
1345
+	 *
1346
+	 * @return CarbonInterface|null
1347
+	 */
1348
+	#[ReturnTypeWillChange]
1349
+	public function current()
1350
+	{
1351
+		return $this->valid()
1352
+			? $this->prepareForReturn($this->current)
1353
+			: null;
1354
+	}
1355
+
1356
+	/**
1357
+	 * Move forward to the next date.
1358
+	 *
1359
+	 * @throws RuntimeException
1360
+	 *
1361
+	 * @return void
1362
+	 */
1363
+	#[ReturnTypeWillChange]
1364
+	public function next()
1365
+	{
1366
+		if ($this->current === null) {
1367
+			$this->rewind();
1368
+		}
1369
+
1370
+		if ($this->validationResult !== static::END_ITERATION) {
1371
+			$this->key++;
1372
+
1373
+			$this->incrementCurrentDateUntilValid();
1374
+		}
1375
+	}
1376
+
1377
+	/**
1378
+	 * Rewind to the start date.
1379
+	 *
1380
+	 * Iterating over a date in the UTC timezone avoids bug during backward DST change.
1381
+	 *
1382
+	 * @see https://bugs.php.net/bug.php?id=72255
1383
+	 * @see https://bugs.php.net/bug.php?id=74274
1384
+	 * @see https://wiki.php.net/rfc/datetime_and_daylight_saving_time
1385
+	 *
1386
+	 * @throws RuntimeException
1387
+	 *
1388
+	 * @return void
1389
+	 */
1390
+	#[ReturnTypeWillChange]
1391
+	public function rewind()
1392
+	{
1393
+		$this->key = 0;
1394
+		$this->current = ([$this->dateClass, 'make'])($this->startDate);
1395
+		$settings = $this->getSettings();
1396
+
1397
+		if ($this->hasLocalTranslator()) {
1398
+			$settings['locale'] = $this->getTranslatorLocale();
1399
+		}
1400
+
1401
+		$this->current->settings($settings);
1402
+		$this->timezone = static::intervalHasTime($this->dateInterval) ? $this->current->getTimezone() : null;
1403
+
1404
+		if ($this->timezone) {
1405
+			$this->current = $this->current->utc();
1406
+		}
1407
+
1408
+		$this->validationResult = null;
1409
+
1410
+		if ($this->isStartExcluded() || $this->validateCurrentDate() === false) {
1411
+			$this->incrementCurrentDateUntilValid();
1412
+		}
1413
+	}
1414
+
1415
+	/**
1416
+	 * Skip iterations and returns iteration state (false if ended, true if still valid).
1417
+	 *
1418
+	 * @param int $count steps number to skip (1 by default)
1419
+	 *
1420
+	 * @return bool
1421
+	 */
1422
+	public function skip($count = 1)
1423
+	{
1424
+		for ($i = $count; $this->valid() && $i > 0; $i--) {
1425
+			$this->next();
1426
+		}
1427
+
1428
+		return $this->valid();
1429
+	}
1430
+
1431
+	/**
1432
+	 * Format the date period as ISO 8601.
1433
+	 *
1434
+	 * @return string
1435
+	 */
1436
+	public function toIso8601String()
1437
+	{
1438
+		$parts = [];
1439
+
1440
+		if ($this->recurrences !== null) {
1441
+			$parts[] = 'R'.$this->recurrences;
1442
+		}
1443
+
1444
+		$parts[] = $this->startDate->toIso8601String();
1445
+
1446
+		$parts[] = $this->dateInterval->spec();
1447
+
1448
+		if ($this->endDate !== null) {
1449
+			$parts[] = $this->endDate->toIso8601String();
1450
+		}
1451
+
1452
+		return implode('/', $parts);
1453
+	}
1454
+
1455
+	/**
1456
+	 * Convert the date period into a string.
1457
+	 *
1458
+	 * @return string
1459
+	 */
1460
+	public function toString()
1461
+	{
1462
+		$translator = ([$this->dateClass, 'getTranslator'])();
1463
+
1464
+		$parts = [];
1465
+
1466
+		$format = !$this->startDate->isStartOfDay() || ($this->endDate && !$this->endDate->isStartOfDay())
1467
+			? 'Y-m-d H:i:s'
1468
+			: 'Y-m-d';
1469
+
1470
+		if ($this->recurrences !== null) {
1471
+			$parts[] = $this->translate('period_recurrences', [], $this->recurrences, $translator);
1472
+		}
1473
+
1474
+		$parts[] = $this->translate('period_interval', [':interval' => $this->dateInterval->forHumans([
1475
+			'join' => true,
1476
+		])], null, $translator);
1477
+
1478
+		$parts[] = $this->translate('period_start_date', [':date' => $this->startDate->rawFormat($format)], null, $translator);
1479
+
1480
+		if ($this->endDate !== null) {
1481
+			$parts[] = $this->translate('period_end_date', [':date' => $this->endDate->rawFormat($format)], null, $translator);
1482
+		}
1483
+
1484
+		$result = implode(' ', $parts);
1485
+
1486
+		return mb_strtoupper(mb_substr($result, 0, 1)).mb_substr($result, 1);
1487
+	}
1488
+
1489
+	/**
1490
+	 * Format the date period as ISO 8601.
1491
+	 *
1492
+	 * @return string
1493
+	 */
1494
+	public function spec()
1495
+	{
1496
+		return $this->toIso8601String();
1497
+	}
1498
+
1499
+	/**
1500
+	 * Cast the current instance into the given class.
1501
+	 *
1502
+	 * @param string $className The $className::instance() method will be called to cast the current object.
1503
+	 *
1504
+	 * @return DatePeriod
1505
+	 */
1506
+	public function cast(string $className)
1507
+	{
1508
+		if (!method_exists($className, 'instance')) {
1509
+			if (is_a($className, DatePeriod::class, true)) {
1510
+				return new $className(
1511
+					$this->rawDate($this->getStartDate()),
1512
+					$this->getDateInterval(),
1513
+					$this->getEndDate() ? $this->rawDate($this->getIncludedEndDate()) : $this->getRecurrences(),
1514
+					$this->isStartExcluded() ? DatePeriod::EXCLUDE_START_DATE : 0
1515
+				);
1516
+			}
1517
+
1518
+			throw new InvalidCastException("$className has not the instance() method needed to cast the date.");
1519
+		}
1520
+
1521
+		return $className::instance($this);
1522
+	}
1523
+
1524
+	/**
1525
+	 * Return native DatePeriod PHP object matching the current instance.
1526
+	 *
1527
+	 * @example
1528
+	 * ```
1529
+	 * var_dump(CarbonPeriod::create('2021-01-05', '2021-02-15')->toDatePeriod());
1530
+	 * ```
1531
+	 *
1532
+	 * @return DatePeriod
1533
+	 */
1534
+	public function toDatePeriod()
1535
+	{
1536
+		return $this->cast(DatePeriod::class);
1537
+	}
1538
+
1539
+	/**
1540
+	 * Return `true` if the period has no custom filter and is guaranteed to be endless.
1541
+	 *
1542
+	 * Note that we can't check if a period is endless as soon as it has custom filters
1543
+	 * because filters can emit `CarbonPeriod::END_ITERATION` to stop the iteration in
1544
+	 * a way we can't predict without actually iterating the period.
1545
+	 */
1546
+	public function isUnfilteredAndEndLess(): bool
1547
+	{
1548
+		foreach ($this->filters as $filter) {
1549
+			switch ($filter) {
1550
+				case [static::RECURRENCES_FILTER, null]:
1551
+					if ($this->recurrences !== null && is_finite($this->recurrences)) {
1552
+						return false;
1553
+					}
1554
+
1555
+					break;
1556
+
1557
+				case [static::END_DATE_FILTER, null]:
1558
+					if ($this->endDate !== null && !$this->endDate->isEndOfTime()) {
1559
+						return false;
1560
+					}
1561
+
1562
+					break;
1563
+
1564
+				default:
1565
+					return false;
1566
+			}
1567
+		}
1568
+
1569
+		return true;
1570
+	}
1571
+
1572
+	/**
1573
+	 * Convert the date period into an array without changing current iteration state.
1574
+	 *
1575
+	 * @return CarbonInterface[]
1576
+	 */
1577
+	public function toArray()
1578
+	{
1579
+		if ($this->isUnfilteredAndEndLess()) {
1580
+			throw new EndLessPeriodException("Endless period can't be converted to array nor counted.");
1581
+		}
1582
+
1583
+		$state = [
1584
+			$this->key,
1585
+			$this->current ? $this->current->avoidMutation() : null,
1586
+			$this->validationResult,
1587
+		];
1588
+
1589
+		$result = iterator_to_array($this);
1590
+
1591
+		[$this->key, $this->current, $this->validationResult] = $state;
1592
+
1593
+		return $result;
1594
+	}
1595
+
1596
+	/**
1597
+	 * Count dates in the date period.
1598
+	 *
1599
+	 * @return int
1600
+	 */
1601
+	#[ReturnTypeWillChange]
1602
+	public function count()
1603
+	{
1604
+		return \count($this->toArray());
1605
+	}
1606
+
1607
+	/**
1608
+	 * Return the first date in the date period.
1609
+	 *
1610
+	 * @return CarbonInterface|null
1611
+	 */
1612
+	public function first()
1613
+	{
1614
+		if ($this->isUnfilteredAndEndLess()) {
1615
+			foreach ($this as $date) {
1616
+				$this->rewind();
1617
+
1618
+				return $date;
1619
+			}
1620
+
1621
+			return null;
1622
+		}
1623
+
1624
+		return ($this->toArray() ?: [])[0] ?? null;
1625
+	}
1626
+
1627
+	/**
1628
+	 * Return the last date in the date period.
1629
+	 *
1630
+	 * @return CarbonInterface|null
1631
+	 */
1632
+	public function last()
1633
+	{
1634
+		$array = $this->toArray();
1635
+
1636
+		return $array ? $array[\count($array) - 1] : null;
1637
+	}
1638
+
1639
+	/**
1640
+	 * Convert the date period into a string.
1641
+	 *
1642
+	 * @return string
1643
+	 */
1644
+	public function __toString()
1645
+	{
1646
+		return $this->toString();
1647
+	}
1648
+
1649
+	/**
1650
+	 * Add aliases for setters.
1651
+	 *
1652
+	 * CarbonPeriod::days(3)->hours(5)->invert()
1653
+	 *     ->sinceNow()->until('2010-01-10')
1654
+	 *     ->filter(...)
1655
+	 *     ->count()
1656
+	 *
1657
+	 * Note: We use magic method to let static and instance aliases with the same names.
1658
+	 *
1659
+	 * @param string $method
1660
+	 * @param array  $parameters
1661
+	 *
1662
+	 * @return mixed
1663
+	 */
1664
+	public function __call($method, $parameters)
1665
+	{
1666
+		if (static::hasMacro($method)) {
1667
+			return static::bindMacroContext($this, function () use (&$method, &$parameters) {
1668
+				return $this->callMacro($method, $parameters);
1669
+			});
1670
+		}
1671
+
1672
+		$roundedValue = $this->callRoundMethod($method, $parameters);
1673
+
1674
+		if ($roundedValue !== null) {
1675
+			return $roundedValue;
1676
+		}
1677
+
1678
+		$first = \count($parameters) >= 1 ? $parameters[0] : null;
1679
+		$second = \count($parameters) >= 2 ? $parameters[1] : null;
1680
+
1681
+		switch ($method) {
1682
+			case 'start':
1683
+			case 'since':
1684
+				return $this->setStartDate($first, $second);
1685
+
1686
+			case 'sinceNow':
1687
+				return $this->setStartDate(new Carbon(), $first);
1688
+
1689
+			case 'end':
1690
+			case 'until':
1691
+				return $this->setEndDate($first, $second);
1692
+
1693
+			case 'untilNow':
1694
+				return $this->setEndDate(new Carbon(), $first);
1695
+
1696
+			case 'dates':
1697
+			case 'between':
1698
+				return $this->setDates($first, $second);
1699
+
1700
+			case 'recurrences':
1701
+			case 'times':
1702
+				return $this->setRecurrences($first);
1703
+
1704
+			case 'options':
1705
+				return $this->setOptions($first);
1706
+
1707
+			case 'toggle':
1708
+				return $this->toggleOptions($first, $second);
1709
+
1710
+			case 'filter':
1711
+			case 'push':
1712
+				return $this->addFilter($first, $second);
1713
+
1714
+			case 'prepend':
1715
+				return $this->prependFilter($first, $second);
1716
+
1717
+			case 'filters':
1718
+				return $this->setFilters($first ?: []);
1719
+
1720
+			case 'interval':
1721
+			case 'each':
1722
+			case 'every':
1723
+			case 'step':
1724
+			case 'stepBy':
1725
+				return $this->setDateInterval($first);
1726
+
1727
+			case 'invert':
1728
+				return $this->invertDateInterval();
1729
+
1730
+			case 'years':
1731
+			case 'year':
1732
+			case 'months':
1733
+			case 'month':
1734
+			case 'weeks':
1735
+			case 'week':
1736
+			case 'days':
1737
+			case 'dayz':
1738
+			case 'day':
1739
+			case 'hours':
1740
+			case 'hour':
1741
+			case 'minutes':
1742
+			case 'minute':
1743
+			case 'seconds':
1744
+			case 'second':
1745
+				return $this->setDateInterval((
1746
+					// Override default P1D when instantiating via fluent setters.
1747
+					[$this->isDefaultInterval ? new CarbonInterval('PT0S') : $this->dateInterval, $method]
1748
+				)(
1749
+					\count($parameters) === 0 ? 1 : $first
1750
+				));
1751
+		}
1752
+
1753
+		if ($this->localStrictModeEnabled ?? Carbon::isStrictModeEnabled()) {
1754
+			throw new UnknownMethodException($method);
1755
+		}
1756
+
1757
+		return $this;
1758
+	}
1759
+
1760
+	/**
1761
+	 * Set the instance's timezone from a string or object and apply it to start/end.
1762
+	 *
1763
+	 * @param \DateTimeZone|string $timezone
1764
+	 *
1765
+	 * @return static
1766
+	 */
1767
+	public function setTimezone($timezone)
1768
+	{
1769
+		$this->tzName = $timezone;
1770
+		$this->timezone = $timezone;
1771
+
1772
+		if ($this->startDate) {
1773
+			$this->setStartDate($this->startDate->setTimezone($timezone));
1774
+		}
1775
+
1776
+		if ($this->endDate) {
1777
+			$this->setEndDate($this->endDate->setTimezone($timezone));
1778
+		}
1779
+
1780
+		return $this;
1781
+	}
1782
+
1783
+	/**
1784
+	 * Set the instance's timezone from a string or object and add/subtract the offset difference to start/end.
1785
+	 *
1786
+	 * @param \DateTimeZone|string $timezone
1787
+	 *
1788
+	 * @return static
1789
+	 */
1790
+	public function shiftTimezone($timezone)
1791
+	{
1792
+		$this->tzName = $timezone;
1793
+		$this->timezone = $timezone;
1794
+
1795
+		if ($this->startDate) {
1796
+			$this->setStartDate($this->startDate->shiftTimezone($timezone));
1797
+		}
1798
+
1799
+		if ($this->endDate) {
1800
+			$this->setEndDate($this->endDate->shiftTimezone($timezone));
1801
+		}
1802
+
1803
+		return $this;
1804
+	}
1805
+
1806
+	/**
1807
+	 * Returns the end is set, else calculated from start an recurrences.
1808
+	 *
1809
+	 * @param string|null $rounding Optional rounding 'floor', 'ceil', 'round' using the period interval.
1810
+	 *
1811
+	 * @return CarbonInterface
1812
+	 */
1813
+	public function calculateEnd(string $rounding = null)
1814
+	{
1815
+		if ($end = $this->getEndDate($rounding)) {
1816
+			return $end;
1817
+		}
1818
+
1819
+		if ($this->dateInterval->isEmpty()) {
1820
+			return $this->getStartDate($rounding);
1821
+		}
1822
+
1823
+		$date = $this->getEndFromRecurrences() ?? $this->iterateUntilEnd();
1824
+
1825
+		if ($date && $rounding) {
1826
+			$date = $date->avoidMutation()->round($this->getDateInterval(), $rounding);
1827
+		}
1828
+
1829
+		return $date;
1830
+	}
1831
+
1832
+	/**
1833
+	 * @return CarbonInterface|null
1834
+	 */
1835
+	private function getEndFromRecurrences()
1836
+	{
1837
+		if ($this->recurrences === null) {
1838
+			throw new UnreachableException(
1839
+				"Could not calculate period end without either explicit end or recurrences.\n".
1840
+				"If you're looking for a forever-period, use ->setRecurrences(INF)."
1841
+			);
1842
+		}
1843
+
1844
+		if ($this->recurrences === INF) {
1845
+			$start = $this->getStartDate();
1846
+
1847
+			return $start < $start->avoidMutation()->add($this->getDateInterval())
1848
+				? CarbonImmutable::endOfTime()
1849
+				: CarbonImmutable::startOfTime();
1850
+		}
1851
+
1852
+		if ($this->filters === [[static::RECURRENCES_FILTER, null]]) {
1853
+			return $this->getStartDate()->avoidMutation()->add(
1854
+				$this->getDateInterval()->times(
1855
+					$this->recurrences - ($this->isStartExcluded() ? 0 : 1)
1856
+				)
1857
+			);
1858
+		}
1859
+
1860
+		return null;
1861
+	}
1862
+
1863
+	/**
1864
+	 * @return CarbonInterface|null
1865
+	 */
1866
+	private function iterateUntilEnd()
1867
+	{
1868
+		$attempts = 0;
1869
+		$date = null;
1870
+
1871
+		foreach ($this as $date) {
1872
+			if (++$attempts > static::END_MAX_ATTEMPTS) {
1873
+				throw new UnreachableException(
1874
+					'Could not calculate period end after iterating '.static::END_MAX_ATTEMPTS.' times.'
1875
+				);
1876
+			}
1877
+		}
1878
+
1879
+		return $date;
1880
+	}
1881
+
1882
+	/**
1883
+	 * Returns true if the current period overlaps the given one (if 1 parameter passed)
1884
+	 * or the period between 2 dates (if 2 parameters passed).
1885
+	 *
1886
+	 * @param CarbonPeriod|\DateTimeInterface|Carbon|CarbonImmutable|string $rangeOrRangeStart
1887
+	 * @param \DateTimeInterface|Carbon|CarbonImmutable|string|null         $rangeEnd
1888
+	 *
1889
+	 * @return bool
1890
+	 */
1891
+	public function overlaps($rangeOrRangeStart, $rangeEnd = null)
1892
+	{
1893
+		$range = $rangeEnd ? static::create($rangeOrRangeStart, $rangeEnd) : $rangeOrRangeStart;
1894
+
1895
+		if (!($range instanceof self)) {
1896
+			$range = static::create($range);
1897
+		}
1898
+
1899
+		[$start, $end] = $this->orderCouple($this->getStartDate(), $this->calculateEnd());
1900
+		[$rangeStart, $rangeEnd] = $this->orderCouple($range->getStartDate(), $range->calculateEnd());
1901
+
1902
+		return $end > $rangeStart && $rangeEnd > $start;
1903
+	}
1904
+
1905
+	/**
1906
+	 * Execute a given function on each date of the period.
1907
+	 *
1908
+	 * @example
1909
+	 * ```
1910
+	 * Carbon::create('2020-11-29')->daysUntil('2020-12-24')->forEach(function (Carbon $date) {
1911
+	 *   echo $date->diffInDays('2020-12-25')." days before Christmas!\n";
1912
+	 * });
1913
+	 * ```
1914
+	 *
1915
+	 * @param callable $callback
1916
+	 */
1917
+	public function forEach(callable $callback)
1918
+	{
1919
+		foreach ($this as $date) {
1920
+			$callback($date);
1921
+		}
1922
+	}
1923
+
1924
+	/**
1925
+	 * Execute a given function on each date of the period and yield the result of this function.
1926
+	 *
1927
+	 * @example
1928
+	 * ```
1929
+	 * $period = Carbon::create('2020-11-29')->daysUntil('2020-12-24');
1930
+	 * echo implode("\n", iterator_to_array($period->map(function (Carbon $date) {
1931
+	 *   return $date->diffInDays('2020-12-25').' days before Christmas!';
1932
+	 * })));
1933
+	 * ```
1934
+	 *
1935
+	 * @param callable $callback
1936
+	 *
1937
+	 * @return \Generator
1938
+	 */
1939
+	public function map(callable $callback)
1940
+	{
1941
+		foreach ($this as $date) {
1942
+			yield $callback($date);
1943
+		}
1944
+	}
1945
+
1946
+	/**
1947
+	 * Determines if the instance is equal to another.
1948
+	 * Warning: if options differ, instances wil never be equal.
1949
+	 *
1950
+	 * @param mixed $period
1951
+	 *
1952
+	 * @see equalTo()
1953
+	 *
1954
+	 * @return bool
1955
+	 */
1956
+	public function eq($period): bool
1957
+	{
1958
+		return $this->equalTo($period);
1959
+	}
1960
+
1961
+	/**
1962
+	 * Determines if the instance is equal to another.
1963
+	 * Warning: if options differ, instances wil never be equal.
1964
+	 *
1965
+	 * @param mixed $period
1966
+	 *
1967
+	 * @return bool
1968
+	 */
1969
+	public function equalTo($period): bool
1970
+	{
1971
+		if (!($period instanceof self)) {
1972
+			$period = self::make($period);
1973
+		}
1974
+
1975
+		$end = $this->getEndDate();
1976
+
1977
+		return $period !== null
1978
+			&& $this->getDateInterval()->eq($period->getDateInterval())
1979
+			&& $this->getStartDate()->eq($period->getStartDate())
1980
+			&& ($end ? $end->eq($period->getEndDate()) : $this->getRecurrences() === $period->getRecurrences())
1981
+			&& ($this->getOptions() & (~static::IMMUTABLE)) === ($period->getOptions() & (~static::IMMUTABLE));
1982
+	}
1983
+
1984
+	/**
1985
+	 * Determines if the instance is not equal to another.
1986
+	 * Warning: if options differ, instances wil never be equal.
1987
+	 *
1988
+	 * @param mixed $period
1989
+	 *
1990
+	 * @see notEqualTo()
1991
+	 *
1992
+	 * @return bool
1993
+	 */
1994
+	public function ne($period): bool
1995
+	{
1996
+		return $this->notEqualTo($period);
1997
+	}
1998
+
1999
+	/**
2000
+	 * Determines if the instance is not equal to another.
2001
+	 * Warning: if options differ, instances wil never be equal.
2002
+	 *
2003
+	 * @param mixed $period
2004
+	 *
2005
+	 * @return bool
2006
+	 */
2007
+	public function notEqualTo($period): bool
2008
+	{
2009
+		return !$this->eq($period);
2010
+	}
2011
+
2012
+	/**
2013
+	 * Determines if the start date is before an other given date.
2014
+	 * (Rather start/end are included by options is ignored.)
2015
+	 *
2016
+	 * @param mixed $date
2017
+	 *
2018
+	 * @return bool
2019
+	 */
2020
+	public function startsBefore($date = null): bool
2021
+	{
2022
+		return $this->getStartDate()->lessThan($this->resolveCarbon($date));
2023
+	}
2024
+
2025
+	/**
2026
+	 * Determines if the start date is before or the same as a given date.
2027
+	 * (Rather start/end are included by options is ignored.)
2028
+	 *
2029
+	 * @param mixed $date
2030
+	 *
2031
+	 * @return bool
2032
+	 */
2033
+	public function startsBeforeOrAt($date = null): bool
2034
+	{
2035
+		return $this->getStartDate()->lessThanOrEqualTo($this->resolveCarbon($date));
2036
+	}
2037
+
2038
+	/**
2039
+	 * Determines if the start date is after an other given date.
2040
+	 * (Rather start/end are included by options is ignored.)
2041
+	 *
2042
+	 * @param mixed $date
2043
+	 *
2044
+	 * @return bool
2045
+	 */
2046
+	public function startsAfter($date = null): bool
2047
+	{
2048
+		return $this->getStartDate()->greaterThan($this->resolveCarbon($date));
2049
+	}
2050
+
2051
+	/**
2052
+	 * Determines if the start date is after or the same as a given date.
2053
+	 * (Rather start/end are included by options is ignored.)
2054
+	 *
2055
+	 * @param mixed $date
2056
+	 *
2057
+	 * @return bool
2058
+	 */
2059
+	public function startsAfterOrAt($date = null): bool
2060
+	{
2061
+		return $this->getStartDate()->greaterThanOrEqualTo($this->resolveCarbon($date));
2062
+	}
2063
+
2064
+	/**
2065
+	 * Determines if the start date is the same as a given date.
2066
+	 * (Rather start/end are included by options is ignored.)
2067
+	 *
2068
+	 * @param mixed $date
2069
+	 *
2070
+	 * @return bool
2071
+	 */
2072
+	public function startsAt($date = null): bool
2073
+	{
2074
+		return $this->getStartDate()->equalTo($this->resolveCarbon($date));
2075
+	}
2076
+
2077
+	/**
2078
+	 * Determines if the end date is before an other given date.
2079
+	 * (Rather start/end are included by options is ignored.)
2080
+	 *
2081
+	 * @param mixed $date
2082
+	 *
2083
+	 * @return bool
2084
+	 */
2085
+	public function endsBefore($date = null): bool
2086
+	{
2087
+		return $this->calculateEnd()->lessThan($this->resolveCarbon($date));
2088
+	}
2089
+
2090
+	/**
2091
+	 * Determines if the end date is before or the same as a given date.
2092
+	 * (Rather start/end are included by options is ignored.)
2093
+	 *
2094
+	 * @param mixed $date
2095
+	 *
2096
+	 * @return bool
2097
+	 */
2098
+	public function endsBeforeOrAt($date = null): bool
2099
+	{
2100
+		return $this->calculateEnd()->lessThanOrEqualTo($this->resolveCarbon($date));
2101
+	}
2102
+
2103
+	/**
2104
+	 * Determines if the end date is after an other given date.
2105
+	 * (Rather start/end are included by options is ignored.)
2106
+	 *
2107
+	 * @param mixed $date
2108
+	 *
2109
+	 * @return bool
2110
+	 */
2111
+	public function endsAfter($date = null): bool
2112
+	{
2113
+		return $this->calculateEnd()->greaterThan($this->resolveCarbon($date));
2114
+	}
2115
+
2116
+	/**
2117
+	 * Determines if the end date is after or the same as a given date.
2118
+	 * (Rather start/end are included by options is ignored.)
2119
+	 *
2120
+	 * @param mixed $date
2121
+	 *
2122
+	 * @return bool
2123
+	 */
2124
+	public function endsAfterOrAt($date = null): bool
2125
+	{
2126
+		return $this->calculateEnd()->greaterThanOrEqualTo($this->resolveCarbon($date));
2127
+	}
2128
+
2129
+	/**
2130
+	 * Determines if the end date is the same as a given date.
2131
+	 * (Rather start/end are included by options is ignored.)
2132
+	 *
2133
+	 * @param mixed $date
2134
+	 *
2135
+	 * @return bool
2136
+	 */
2137
+	public function endsAt($date = null): bool
2138
+	{
2139
+		return $this->calculateEnd()->equalTo($this->resolveCarbon($date));
2140
+	}
2141
+
2142
+	/**
2143
+	 * Return true if start date is now or later.
2144
+	 * (Rather start/end are included by options is ignored.)
2145
+	 *
2146
+	 * @return bool
2147
+	 */
2148
+	public function isStarted(): bool
2149
+	{
2150
+		return $this->startsBeforeOrAt();
2151
+	}
2152
+
2153
+	/**
2154
+	 * Return true if end date is now or later.
2155
+	 * (Rather start/end are included by options is ignored.)
2156
+	 *
2157
+	 * @return bool
2158
+	 */
2159
+	public function isEnded(): bool
2160
+	{
2161
+		return $this->endsBeforeOrAt();
2162
+	}
2163
+
2164
+	/**
2165
+	 * Return true if now is between start date (included) and end date (excluded).
2166
+	 * (Rather start/end are included by options is ignored.)
2167
+	 *
2168
+	 * @return bool
2169
+	 */
2170
+	public function isInProgress(): bool
2171
+	{
2172
+		return $this->isStarted() && !$this->isEnded();
2173
+	}
2174
+
2175
+	/**
2176
+	 * Round the current instance at the given unit with given precision if specified and the given function.
2177
+	 *
2178
+	 * @param string                              $unit
2179
+	 * @param float|int|string|\DateInterval|null $precision
2180
+	 * @param string                              $function
2181
+	 *
2182
+	 * @return $this
2183
+	 */
2184
+	public function roundUnit($unit, $precision = 1, $function = 'round')
2185
+	{
2186
+		$this->setStartDate($this->getStartDate()->roundUnit($unit, $precision, $function));
2187
+
2188
+		if ($this->endDate) {
2189
+			$this->setEndDate($this->getEndDate()->roundUnit($unit, $precision, $function));
2190
+		}
2191
+
2192
+		$this->setDateInterval($this->getDateInterval()->roundUnit($unit, $precision, $function));
2193
+
2194
+		return $this;
2195
+	}
2196
+
2197
+	/**
2198
+	 * Truncate the current instance at the given unit with given precision if specified.
2199
+	 *
2200
+	 * @param string                              $unit
2201
+	 * @param float|int|string|\DateInterval|null $precision
2202
+	 *
2203
+	 * @return $this
2204
+	 */
2205
+	public function floorUnit($unit, $precision = 1)
2206
+	{
2207
+		return $this->roundUnit($unit, $precision, 'floor');
2208
+	}
2209
+
2210
+	/**
2211
+	 * Ceil the current instance at the given unit with given precision if specified.
2212
+	 *
2213
+	 * @param string                              $unit
2214
+	 * @param float|int|string|\DateInterval|null $precision
2215
+	 *
2216
+	 * @return $this
2217
+	 */
2218
+	public function ceilUnit($unit, $precision = 1)
2219
+	{
2220
+		return $this->roundUnit($unit, $precision, 'ceil');
2221
+	}
2222
+
2223
+	/**
2224
+	 * Round the current instance second with given precision if specified (else period interval is used).
2225
+	 *
2226
+	 * @param float|int|string|\DateInterval|null $precision
2227
+	 * @param string                              $function
2228
+	 *
2229
+	 * @return $this
2230
+	 */
2231
+	public function round($precision = null, $function = 'round')
2232
+	{
2233
+		return $this->roundWith(
2234
+			$precision ?? $this->getDateInterval()->setLocalTranslator(TranslatorImmutable::get('en'))->forHumans(),
2235
+			$function
2236
+		);
2237
+	}
2238
+
2239
+	/**
2240
+	 * Round the current instance second with given precision if specified (else period interval is used).
2241
+	 *
2242
+	 * @param float|int|string|\DateInterval|null $precision
2243
+	 *
2244
+	 * @return $this
2245
+	 */
2246
+	public function floor($precision = null)
2247
+	{
2248
+		return $this->round($precision, 'floor');
2249
+	}
2250
+
2251
+	/**
2252
+	 * Ceil the current instance second with given precision if specified (else period interval is used).
2253
+	 *
2254
+	 * @param float|int|string|\DateInterval|null $precision
2255
+	 *
2256
+	 * @return $this
2257
+	 */
2258
+	public function ceil($precision = null)
2259
+	{
2260
+		return $this->round($precision, 'ceil');
2261
+	}
2262
+
2263
+	/**
2264
+	 * Specify data which should be serialized to JSON.
2265
+	 *
2266
+	 * @link https://php.net/manual/en/jsonserializable.jsonserialize.php
2267
+	 *
2268
+	 * @return CarbonInterface[]
2269
+	 */
2270
+	#[ReturnTypeWillChange]
2271
+	public function jsonSerialize()
2272
+	{
2273
+		return $this->toArray();
2274
+	}
2275
+
2276
+	/**
2277
+	 * Return true if the given date is between start and end.
2278
+	 *
2279
+	 * @param \Carbon\Carbon|\Carbon\CarbonPeriod|\Carbon\CarbonInterval|\DateInterval|\DatePeriod|\DateTimeInterface|string|null $date
2280
+	 *
2281
+	 * @return bool
2282
+	 */
2283
+	public function contains($date = null): bool
2284
+	{
2285
+		$startMethod = 'startsBefore'.($this->isStartIncluded() ? 'OrAt' : '');
2286
+		$endMethod = 'endsAfter'.($this->isEndIncluded() ? 'OrAt' : '');
2287
+
2288
+		return $this->$startMethod($date) && $this->$endMethod($date);
2289
+	}
2290
+
2291
+	/**
2292
+	 * Return true if the current period follows a given other period (with no overlap).
2293
+	 * For instance, [2019-08-01 -> 2019-08-12] follows [2019-07-29 -> 2019-07-31]
2294
+	 * Note than in this example, follows() would be false if 2019-08-01 or 2019-07-31 was excluded by options.
2295
+	 *
2296
+	 * @param \Carbon\CarbonPeriod|\DatePeriod|string $period
2297
+	 *
2298
+	 * @return bool
2299
+	 */
2300
+	public function follows($period, ...$arguments): bool
2301
+	{
2302
+		$period = $this->resolveCarbonPeriod($period, ...$arguments);
2303
+
2304
+		return $this->getIncludedStartDate()->equalTo($period->getIncludedEndDate()->add($period->getDateInterval()));
2305
+	}
2306
+
2307
+	/**
2308
+	 * Return true if the given other period follows the current one (with no overlap).
2309
+	 * For instance, [2019-07-29 -> 2019-07-31] is followed by [2019-08-01 -> 2019-08-12]
2310
+	 * Note than in this example, isFollowedBy() would be false if 2019-08-01 or 2019-07-31 was excluded by options.
2311
+	 *
2312
+	 * @param \Carbon\CarbonPeriod|\DatePeriod|string $period
2313
+	 *
2314
+	 * @return bool
2315
+	 */
2316
+	public function isFollowedBy($period, ...$arguments): bool
2317
+	{
2318
+		$period = $this->resolveCarbonPeriod($period, ...$arguments);
2319
+
2320
+		return $period->follows($this);
2321
+	}
2322
+
2323
+	/**
2324
+	 * Return true if the given period either follows or is followed by the current one.
2325
+	 *
2326
+	 * @see follows()
2327
+	 * @see isFollowedBy()
2328
+	 *
2329
+	 * @param \Carbon\CarbonPeriod|\DatePeriod|string $period
2330
+	 *
2331
+	 * @return bool
2332
+	 */
2333
+	public function isConsecutiveWith($period, ...$arguments): bool
2334
+	{
2335
+		return $this->follows($period, ...$arguments) || $this->isFollowedBy($period, ...$arguments);
2336
+	}
2337
+
2338
+	/**
2339
+	 * Update properties after removing built-in filters.
2340
+	 *
2341
+	 * @return void
2342
+	 */
2343
+	protected function updateInternalState()
2344
+	{
2345
+		if (!$this->hasFilter(static::END_DATE_FILTER)) {
2346
+			$this->endDate = null;
2347
+		}
2348
+
2349
+		if (!$this->hasFilter(static::RECURRENCES_FILTER)) {
2350
+			$this->recurrences = null;
2351
+		}
2352
+	}
2353
+
2354
+	/**
2355
+	 * Create a filter tuple from raw parameters.
2356
+	 *
2357
+	 * Will create an automatic filter callback for one of Carbon's is* methods.
2358
+	 *
2359
+	 * @param array $parameters
2360
+	 *
2361
+	 * @return array
2362
+	 */
2363
+	protected function createFilterTuple(array $parameters)
2364
+	{
2365
+		$method = array_shift($parameters);
2366
+
2367
+		if (!$this->isCarbonPredicateMethod($method)) {
2368
+			return [$method, array_shift($parameters)];
2369
+		}
2370
+
2371
+		return [function ($date) use ($method, $parameters) {
2372
+			return ([$date, $method])(...$parameters);
2373
+		}, $method];
2374
+	}
2375
+
2376
+	/**
2377
+	 * Return whether given callable is a string pointing to one of Carbon's is* methods
2378
+	 * and should be automatically converted to a filter callback.
2379
+	 *
2380
+	 * @param callable $callable
2381
+	 *
2382
+	 * @return bool
2383
+	 */
2384
+	protected function isCarbonPredicateMethod($callable)
2385
+	{
2386
+		return \is_string($callable) && str_starts_with($callable, 'is') &&
2387
+			(method_exists($this->dateClass, $callable) || ([$this->dateClass, 'hasMacro'])($callable));
2388
+	}
2389
+
2390
+	/**
2391
+	 * Recurrences filter callback (limits number of recurrences).
2392
+	 *
2393
+	 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
2394
+	 *
2395
+	 * @param \Carbon\Carbon $current
2396
+	 * @param int            $key
2397
+	 *
2398
+	 * @return bool|string
2399
+	 */
2400
+	protected function filterRecurrences($current, $key)
2401
+	{
2402
+		if ($key < $this->recurrences) {
2403
+			return true;
2404
+		}
2405
+
2406
+		return static::END_ITERATION;
2407
+	}
2408
+
2409
+	/**
2410
+	 * End date filter callback.
2411
+	 *
2412
+	 * @param \Carbon\Carbon $current
2413
+	 *
2414
+	 * @return bool|string
2415
+	 */
2416
+	protected function filterEndDate($current)
2417
+	{
2418
+		if (!$this->isEndExcluded() && $current == $this->endDate) {
2419
+			return true;
2420
+		}
2421
+
2422
+		if ($this->dateInterval->invert ? $current > $this->endDate : $current < $this->endDate) {
2423
+			return true;
2424
+		}
2425
+
2426
+		return static::END_ITERATION;
2427
+	}
2428
+
2429
+	/**
2430
+	 * End iteration filter callback.
2431
+	 *
2432
+	 * @return string
2433
+	 */
2434
+	protected function endIteration()
2435
+	{
2436
+		return static::END_ITERATION;
2437
+	}
2438
+
2439
+	/**
2440
+	 * Handle change of the parameters.
2441
+	 */
2442
+	protected function handleChangedParameters()
2443
+	{
2444
+		if (($this->getOptions() & static::IMMUTABLE) && $this->dateClass === Carbon::class) {
2445
+			$this->setDateClass(CarbonImmutable::class);
2446
+		} elseif (!($this->getOptions() & static::IMMUTABLE) && $this->dateClass === CarbonImmutable::class) {
2447
+			$this->setDateClass(Carbon::class);
2448
+		}
2449
+
2450
+		$this->validationResult = null;
2451
+	}
2452
+
2453
+	/**
2454
+	 * Validate current date and stop iteration when necessary.
2455
+	 *
2456
+	 * Returns true when current date is valid, false if it is not, or static::END_ITERATION
2457
+	 * when iteration should be stopped.
2458
+	 *
2459
+	 * @return bool|string
2460
+	 */
2461
+	protected function validateCurrentDate()
2462
+	{
2463
+		if ($this->current === null) {
2464
+			$this->rewind();
2465
+		}
2466
+
2467
+		// Check after the first rewind to avoid repeating the initial validation.
2468
+		return $this->validationResult ?? ($this->validationResult = $this->checkFilters());
2469
+	}
2470
+
2471
+	/**
2472
+	 * Check whether current value and key pass all the filters.
2473
+	 *
2474
+	 * @return bool|string
2475
+	 */
2476
+	protected function checkFilters()
2477
+	{
2478
+		$current = $this->prepareForReturn($this->current);
2479
+
2480
+		foreach ($this->filters as $tuple) {
2481
+			$result = \call_user_func(
2482
+				$tuple[0],
2483
+				$current->avoidMutation(),
2484
+				$this->key,
2485
+				$this
2486
+			);
2487
+
2488
+			if ($result === static::END_ITERATION) {
2489
+				return static::END_ITERATION;
2490
+			}
2491
+
2492
+			if (!$result) {
2493
+				return false;
2494
+			}
2495
+		}
2496
+
2497
+		return true;
2498
+	}
2499
+
2500
+	/**
2501
+	 * Prepare given date to be returned to the external logic.
2502
+	 *
2503
+	 * @param CarbonInterface $date
2504
+	 *
2505
+	 * @return CarbonInterface
2506
+	 */
2507
+	protected function prepareForReturn(CarbonInterface $date)
2508
+	{
2509
+		$date = ([$this->dateClass, 'make'])($date);
2510
+
2511
+		if ($this->timezone) {
2512
+			$date = $date->setTimezone($this->timezone);
2513
+		}
2514
+
2515
+		return $date;
2516
+	}
2517
+
2518
+	/**
2519
+	 * Keep incrementing the current date until a valid date is found or the iteration is ended.
2520
+	 *
2521
+	 * @throws RuntimeException
2522
+	 *
2523
+	 * @return void
2524
+	 */
2525
+	protected function incrementCurrentDateUntilValid()
2526
+	{
2527
+		$attempts = 0;
2528
+
2529
+		do {
2530
+			$this->current = $this->current->add($this->dateInterval);
2531
+
2532
+			$this->validationResult = null;
2533
+
2534
+			if (++$attempts > static::NEXT_MAX_ATTEMPTS) {
2535
+				throw new UnreachableException('Could not find next valid date.');
2536
+			}
2537
+		} while ($this->validateCurrentDate() === false);
2538
+	}
2539
+
2540
+	/**
2541
+	 * Call given macro.
2542
+	 *
2543
+	 * @param string $name
2544
+	 * @param array  $parameters
2545
+	 *
2546
+	 * @return mixed
2547
+	 */
2548
+	protected function callMacro($name, $parameters)
2549
+	{
2550
+		$macro = static::$macros[$name];
2551
+
2552
+		if ($macro instanceof Closure) {
2553
+			$boundMacro = @$macro->bindTo($this, static::class) ?: @$macro->bindTo(null, static::class);
2554
+
2555
+			return ($boundMacro ?: $macro)(...$parameters);
2556
+		}
2557
+
2558
+		return $macro(...$parameters);
2559
+	}
2560
+
2561
+	/**
2562
+	 * Return the Carbon instance passed through, a now instance in the same timezone
2563
+	 * if null given or parse the input if string given.
2564
+	 *
2565
+	 * @param \Carbon\Carbon|\Carbon\CarbonPeriod|\Carbon\CarbonInterval|\DateInterval|\DatePeriod|\DateTimeInterface|string|null $date
2566
+	 *
2567
+	 * @return \Carbon\CarbonInterface
2568
+	 */
2569
+	protected function resolveCarbon($date = null)
2570
+	{
2571
+		return $this->getStartDate()->nowWithSameTz()->carbonize($date);
2572
+	}
2573
+
2574
+	/**
2575
+	 * Resolve passed arguments or DatePeriod to a CarbonPeriod object.
2576
+	 *
2577
+	 * @param mixed $period
2578
+	 * @param mixed ...$arguments
2579
+	 *
2580
+	 * @return static
2581
+	 */
2582
+	protected function resolveCarbonPeriod($period, ...$arguments)
2583
+	{
2584
+		if ($period instanceof self) {
2585
+			return $period;
2586
+		}
2587
+
2588
+		return $period instanceof DatePeriod
2589
+			? static::instance($period)
2590
+			: static::create($period, ...$arguments);
2591
+	}
2592
+
2593
+	private function orderCouple($first, $second): array
2594
+	{
2595
+		return $first > $second ? [$second, $first] : [$first, $second];
2596
+	}
2597
+
2598
+	private function makeDateTime($value): ?DateTimeInterface
2599
+	{
2600
+		if ($value instanceof DateTimeInterface) {
2601
+			return $value;
2602
+		}
2603
+
2604
+		if (\is_string($value)) {
2605
+			$value = trim($value);
2606
+
2607
+			if (!preg_match('/^P[\dT]/', $value) &&
2608
+				!preg_match('/^R\d/', $value) &&
2609
+				preg_match('/[a-z\d]/i', $value)
2610
+			) {
2611
+				return Carbon::parse($value, $this->tzName);
2612
+			}
2613
+		}
2614
+
2615
+		return null;
2616
+	}
2617
+
2618
+	private function isInfiniteDate($date): bool
2619
+	{
2620
+		return $date instanceof CarbonInterface && ($date->isEndOfTime() || $date->isStartOfTime());
2621
+	}
2622
+
2623
+	private function rawDate($date): ?DateTimeInterface
2624
+	{
2625
+		if ($date === false || $date === null) {
2626
+			return null;
2627
+		}
2628
+
2629
+		if ($date instanceof CarbonInterface) {
2630
+			return $date->isMutable()
2631
+				? $date->toDateTime()
2632
+				: $date->toDateTimeImmutable();
2633
+		}
2634
+
2635
+		if (\in_array(\get_class($date), [DateTime::class, DateTimeImmutable::class], true)) {
2636
+			return $date;
2637
+		}
2638
+
2639
+		$class = $date instanceof DateTime ? DateTime::class : DateTimeImmutable::class;
2640
+
2641
+		return new $class($date->format('Y-m-d H:i:s.u'), $date->getTimezone());
2642
+	}
2643 2643
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -7 removed lines patch added patch discarded remove patch
@@ -606,7 +606,7 @@  discard block
 block discarded – undo
606 606
         $date = new static();
607 607
 
608 608
         if (static::hasMacro($method)) {
609
-            return static::bindMacroContext(null, function () use (&$method, &$parameters, &$date) {
609
+            return static::bindMacroContext(null, function() use (&$method, &$parameters, &$date) {
610 610
                 return $date->callMacro($method, $parameters);
611 611
             });
612 612
         }
@@ -931,8 +931,7 @@  discard block
 block discarded – undo
931 931
 
932 932
         return $this->setOptions(
933 933
             $state ?
934
-            $this->options | $options :
935
-            $this->options & ~$options
934
+            $this->options | $options : $this->options & ~$options
936 935
         );
937 936
     }
938 937
 
@@ -1144,7 +1143,7 @@  discard block
 block discarded – undo
1144 1143
 
1145 1144
         $this->filters = array_values(array_filter(
1146 1145
             $this->filters,
1147
-            function ($tuple) use ($key, $filter) {
1146
+            function($tuple) use ($key, $filter) {
1148 1147
                 return $tuple[$key] !== $filter;
1149 1148
             }
1150 1149
         ));
@@ -1664,7 +1663,7 @@  discard block
 block discarded – undo
1664 1663
     public function __call($method, $parameters)
1665 1664
     {
1666 1665
         if (static::hasMacro($method)) {
1667
-            return static::bindMacroContext($this, function () use (&$method, &$parameters) {
1666
+            return static::bindMacroContext($this, function() use (&$method, &$parameters) {
1668 1667
                 return $this->callMacro($method, $parameters);
1669 1668
             });
1670 1669
         }
@@ -1914,7 +1913,7 @@  discard block
 block discarded – undo
1914 1913
      *
1915 1914
      * @param callable $callback
1916 1915
      */
1917
-    public function forEach(callable $callback)
1916
+    public function forEach (callable $callback)
1918 1917
     {
1919 1918
         foreach ($this as $date) {
1920 1919
             $callback($date);
@@ -2368,7 +2367,7 @@  discard block
 block discarded – undo
2368 2367
             return [$method, array_shift($parameters)];
2369 2368
         }
2370 2369
 
2371
-        return [function ($date) use ($method, $parameters) {
2370
+        return [function($date) use ($method, $parameters) {
2372 2371
             return ([$date, $method])(...$parameters);
2373 2372
         }, $method];
2374 2373
     }
Please login to merge, or discard this patch.
Upper-Lower-Casing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1914,7 +1914,7 @@
 block discarded – undo
1914 1914
      *
1915 1915
      * @param callable $callback
1916 1916
      */
1917
-    public function forEach(callable $callback)
1917
+    public function foreach(callable $callback)
1918 1918
     {
1919 1919
         foreach ($this as $date) {
1920 1920
             $callback($date);
Please login to merge, or discard this patch.
vendor/nesbot/carbon/src/Carbon/Exceptions/EndLessPeriodException.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -15,5 +15,5 @@
 block discarded – undo
15 15
 
16 16
 final class EndLessPeriodException extends BaseRuntimeException implements RuntimeException
17 17
 {
18
-    //
18
+	//
19 19
 }
Please login to merge, or discard this patch.
vendor/nesbot/carbon/src/Carbon/Exceptions/InvalidIntervalException.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -15,5 +15,5 @@
 block discarded – undo
15 15
 
16 16
 class InvalidIntervalException extends BaseInvalidArgumentException implements InvalidArgumentException
17 17
 {
18
-    //
18
+	//
19 19
 }
Please login to merge, or discard this patch.
php-imap/vendor/nesbot/carbon/src/Carbon/Exceptions/ImmutableException.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -16,33 +16,33 @@
 block discarded – undo
16 16
 
17 17
 class ImmutableException extends BaseRuntimeException implements RuntimeException
18 18
 {
19
-    /**
20
-     * The value.
21
-     *
22
-     * @var string
23
-     */
24
-    protected $value;
19
+	/**
20
+	 * The value.
21
+	 *
22
+	 * @var string
23
+	 */
24
+	protected $value;
25 25
 
26
-    /**
27
-     * Constructor.
28
-     *
29
-     * @param string         $value    the immutable type/value
30
-     * @param int            $code
31
-     * @param Throwable|null $previous
32
-     */
33
-    public function __construct($value, $code = 0, Throwable $previous = null)
34
-    {
35
-        $this->value = $value;
36
-        parent::__construct("$value is immutable.", $code, $previous);
37
-    }
26
+	/**
27
+	 * Constructor.
28
+	 *
29
+	 * @param string         $value    the immutable type/value
30
+	 * @param int            $code
31
+	 * @param Throwable|null $previous
32
+	 */
33
+	public function __construct($value, $code = 0, Throwable $previous = null)
34
+	{
35
+		$this->value = $value;
36
+		parent::__construct("$value is immutable.", $code, $previous);
37
+	}
38 38
 
39
-    /**
40
-     * Get the value.
41
-     *
42
-     * @return string
43
-     */
44
-    public function getValue(): string
45
-    {
46
-        return $this->value;
47
-    }
39
+	/**
40
+	 * Get the value.
41
+	 *
42
+	 * @return string
43
+	 */
44
+	public function getValue(): string
45
+	{
46
+		return $this->value;
47
+	}
48 48
 }
Please login to merge, or discard this patch.
vendor/nesbot/carbon/src/Carbon/Exceptions/InvalidDateException.php 1 patch
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -16,52 +16,52 @@
 block discarded – undo
16 16
 
17 17
 class InvalidDateException extends BaseInvalidArgumentException implements InvalidArgumentException
18 18
 {
19
-    /**
20
-     * The invalid field.
21
-     *
22
-     * @var string
23
-     */
24
-    private $field;
19
+	/**
20
+	 * The invalid field.
21
+	 *
22
+	 * @var string
23
+	 */
24
+	private $field;
25 25
 
26
-    /**
27
-     * The invalid value.
28
-     *
29
-     * @var mixed
30
-     */
31
-    private $value;
26
+	/**
27
+	 * The invalid value.
28
+	 *
29
+	 * @var mixed
30
+	 */
31
+	private $value;
32 32
 
33
-    /**
34
-     * Constructor.
35
-     *
36
-     * @param string         $field
37
-     * @param mixed          $value
38
-     * @param int            $code
39
-     * @param Throwable|null $previous
40
-     */
41
-    public function __construct($field, $value, $code = 0, Throwable $previous = null)
42
-    {
43
-        $this->field = $field;
44
-        $this->value = $value;
45
-        parent::__construct($field.' : '.$value.' is not a valid value.', $code, $previous);
46
-    }
33
+	/**
34
+	 * Constructor.
35
+	 *
36
+	 * @param string         $field
37
+	 * @param mixed          $value
38
+	 * @param int            $code
39
+	 * @param Throwable|null $previous
40
+	 */
41
+	public function __construct($field, $value, $code = 0, Throwable $previous = null)
42
+	{
43
+		$this->field = $field;
44
+		$this->value = $value;
45
+		parent::__construct($field.' : '.$value.' is not a valid value.', $code, $previous);
46
+	}
47 47
 
48
-    /**
49
-     * Get the invalid field.
50
-     *
51
-     * @return string
52
-     */
53
-    public function getField()
54
-    {
55
-        return $this->field;
56
-    }
48
+	/**
49
+	 * Get the invalid field.
50
+	 *
51
+	 * @return string
52
+	 */
53
+	public function getField()
54
+	{
55
+		return $this->field;
56
+	}
57 57
 
58
-    /**
59
-     * Get the invalid value.
60
-     *
61
-     * @return mixed
62
-     */
63
-    public function getValue()
64
-    {
65
-        return $this->value;
66
-    }
58
+	/**
59
+	 * Get the invalid value.
60
+	 *
61
+	 * @return mixed
62
+	 */
63
+	public function getValue()
64
+	{
65
+		return $this->value;
66
+	}
67 67
 }
Please login to merge, or discard this patch.