PluginProbe
Yatra – Travel Booking & Tour Operator Software / 2.2.10
Yatra – Travel Booking & Tour Operator Software v2.2.10
3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 2.0.11 All 82 releases
yatra / core / Libraries / Carbon.php

Carbon.php in Yatra – Travel Booking & Tour Operator Software 2.2.10, at core/Libraries/Carbon.php

3,371 lines 69.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * This file is part of the Carbon package.
5 *
6 * (c) Brian Nesbitt <brian@nesbot.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Carbon;
13
14 use Carbon\Exceptions\InvalidDateException;
15 use Closure;
16 use DatePeriod;
17 use DateTime;
18 use DateTimeZone;
19 use InvalidArgumentException;
20 use Symfony\Component\Translation\Loader\ArrayLoader;
21 use Symfony\Component\Translation\Translator;
22 use Symfony\Component\Translation\TranslatorInterface;
23
24 /**
25 * A simple API extension for DateTime
26 *
27 * @property int $year
28 * @property int $yearIso
29 * @property int $month
30 * @property int $day
31 * @property int $hour
32 * @property int $minute
33 * @property int $second
34 * @property int $timestamp seconds since the Unix Epoch
35 * @property \DateTimeZone $timezone the current timezone
36 * @property \DateTimeZone $tz alias of timezone
37 * @property-read int $micro
38 * @property-read int $dayOfWeek 0 (for Sunday) through 6 (for Saturday)
39 * @property-read int $dayOfYear 0 through 365
40 * @property-read int $weekOfMonth 1 through 5
41 * @property-read int $weekOfYear ISO-8601 week number of year, weeks starting on Monday
42 * @property-read int $daysInMonth number of days in the given month
43 * @property-read int $age does a diffInYears() with default parameters
44 * @property-read int $quarter the quarter of this instance, 1 - 4
45 * @property-read int $offset the timezone offset in seconds from UTC
46 * @property-read int $offsetHours the timezone offset in hours from UTC
47 * @property-read bool $dst daylight savings time indicator, true if DST, false otherwise
48 * @property-read bool $local checks if the timezone is local, true if local, false otherwise
49 * @property-read bool $utc checks if the timezone is UTC, true if UTC, false otherwise
50 * @property-read string $timezoneName
51 * @property-read string $tzName
52 */
53 class Carbon extends DateTime
54 {
55 /**
56 * The day constants.
57 */
58 const SUNDAY = 0;
59 const MONDAY = 1;
60 const TUESDAY = 2;
61 const WEDNESDAY = 3;
62 const THURSDAY = 4;
63 const FRIDAY = 5;
64 const SATURDAY = 6;
65
66 /**
67 * Names of days of the week.
68 *
69 * @var array
70 */
71 protected static $days = array(
72 self::SUNDAY => 'Sunday',
73 self::MONDAY => 'Monday',
74 self::TUESDAY => 'Tuesday',
75 self::WEDNESDAY => 'Wednesday',
76 self::THURSDAY => 'Thursday',
77 self::FRIDAY => 'Friday',
78 self::SATURDAY => 'Saturday',
79 );
80
81 /**
82 * Terms used to detect if a time passed is a relative date.
83 *
84 * This is here for testing purposes.
85 *
86 * @var array
87 */
88 protected static $relativeKeywords = array(
89 '+',
90 '-',
91 'ago',
92 'first',
93 'last',
94 'next',
95 'this',
96 'today',
97 'tomorrow',
98 'yesterday',
99 );
100
101 /**
102 * Number of X in Y.
103 */
104 const YEARS_PER_CENTURY = 100;
105 const YEARS_PER_DECADE = 10;
106 const MONTHS_PER_YEAR = 12;
107 const MONTHS_PER_QUARTER = 3;
108 const WEEKS_PER_YEAR = 52;
109 const DAYS_PER_WEEK = 7;
110 const HOURS_PER_DAY = 24;
111 const MINUTES_PER_HOUR = 60;
112 const SECONDS_PER_MINUTE = 60;
113
114 /**
115 * Default format to use for __toString method when type juggling occurs.
116 *
117 * @var string
118 */
119 const DEFAULT_TO_STRING_FORMAT = 'Y-m-d H:i:s';
120
121 /**
122 * Format to use for __toString method when type juggling occurs.
123 *
124 * @var string
125 */
126 protected static $toStringFormat = self::DEFAULT_TO_STRING_FORMAT;
127
128 /**
129 * First day of week.
130 *
131 * @var int
132 */
133 protected static $weekStartsAt = self::MONDAY;
134
135 /**
136 * Last day of week.
137 *
138 * @var int
139 */
140 protected static $weekEndsAt = self::SUNDAY;
141
142 /**
143 * Days of weekend.
144 *
145 * @var array
146 */
147 protected static $weekendDays = array(
148 self::SATURDAY,
149 self::SUNDAY,
150 );
151
152 /**
153 * A test Carbon instance to be returned when now instances are created.
154 *
155 * @var \Carbon\Carbon
156 */
157 protected static $testNow;
158
159 /**
160 * A translator to ... er ... translate stuff.
161 *
162 * @var \Symfony\Component\Translation\TranslatorInterface
163 */
164 protected static $translator;
165
166 /**
167 * The errors that can occur.
168 *
169 * @var array
170 */
171 protected static $lastErrors;
172
173 /**
174 * Will UTF8 encoding be used to print localized date/time ?
175 *
176 * @var bool
177 */
178 protected static $utf8 = false;
179
180 /*
181 * Indicates if months should be calculated with overflow.
182 *
183 * @var bool
184 */
185 protected static $monthsOverflow = true;
186
187 /**
188 * Indicates if months should be calculated with overflow.
189 *
190 * @param bool $monthsOverflow
191 *
192 * @return void
193 */
194 public static function useMonthsOverflow($monthsOverflow = true)
195 {
196 static::$monthsOverflow = $monthsOverflow;
197 }
198
199 /**
200 * Reset the month overflow behavior.
201 *
202 * @return void
203 */
204 public static function resetMonthsOverflow()
205 {
206 static::$monthsOverflow = true;
207 }
208
209 /**
210 * Get the month overflow behavior.
211 *
212 * @return bool
213 */
214 public static function shouldOverflowMonths()
215 {
216 return static::$monthsOverflow;
217 }
218
219 /**
220 * Creates a DateTimeZone from a string, DateTimeZone or integer offset.
221 *
222 * @param \DateTimeZone|string|int|null $object
223 *
224 * @throws \InvalidArgumentException
225 *
226 * @return \DateTimeZone
227 */
228 protected static function safeCreateDateTimeZone($object)
229 {
230 if ($object === null) {
231 // Don't return null... avoid Bug #52063 in PHP <5.3.6
232 return new DateTimeZone(date_default_timezone_get());
233 }
234
235 if ($object instanceof DateTimeZone) {
236 return $object;
237 }
238
239 if (is_numeric($object)) {
240 $tzName = timezone_name_from_abbr(null, $object * 3600, true);
241
242 if ($tzName === false) {
243 throw new InvalidArgumentException('Unknown or bad timezone ('.$object.')');
244 }
245
246 $object = $tzName;
247 }
248
249 $tz = @timezone_open((string) $object);
250
251 if ($tz === false) {
252 throw new InvalidArgumentException('Unknown or bad timezone ('.$object.')');
253 }
254
255 return $tz;
256 }
257
258 ///////////////////////////////////////////////////////////////////
259 //////////////////////////// CONSTRUCTORS /////////////////////////
260 ///////////////////////////////////////////////////////////////////
261
262 /**
263 * Create a new Carbon instance.
264 *
265 * Please see the testing aids section (specifically static::setTestNow())
266 * for more on the possibility of this constructor returning a test instance.
267 *
268 * @param string|null $time
269 * @param \DateTimeZone|string|null $tz
270 */
271 public function __construct($time = null, $tz = null)
272 {
273 // If the class has a test now set and we are trying to create a now()
274 // instance then override as required
275 if (static::hasTestNow() && (empty($time) || $time === 'now' || static::hasRelativeKeywords($time))) {
276 $testInstance = clone static::getTestNow();
277 if (static::hasRelativeKeywords($time)) {
278 $testInstance->modify($time);
279 }
280
281 //shift the time according to the given time zone
282 if ($tz !== null && $tz !== static::getTestNow()->getTimezone()) {
283 $testInstance->setTimezone($tz);
284 } else {
285 $tz = $testInstance->getTimezone();
286 }
287
288 $time = $testInstance->toDateTimeString();
289 }
290
291 parent::__construct($time, static::safeCreateDateTimeZone($tz));
292 }
293
294 /**
295 * Create a Carbon instance from a DateTime one.
296 *
297 * @param \DateTime $dt
298 *
299 * @return static
300 */
301 public static function instance(DateTime $dt)
302 {
303 if ($dt instanceof static) {
304 return clone $dt;
305 }
306
307 return new static($dt->format('Y-m-d H:i:s.u'), $dt->getTimezone());
308 }
309
310 /**
311 * Create a carbon instance from a string.
312 *
313 * This is an alias for the constructor that allows better fluent syntax
314 * as it allows you to do Carbon::parse('Monday next week')->fn() rather
315 * than (new Carbon('Monday next week'))->fn().
316 *
317 * @param string|null $time
318 * @param \DateTimeZone|string|null $tz
319 *
320 * @return static
321 */
322 public static function parse($time = null, $tz = null)
323 {
324 return new static($time, $tz);
325 }
326
327 /**
328 * Get a Carbon instance for the current date and time.
329 *
330 * @param \DateTimeZone|string|null $tz
331 *
332 * @return static
333 */
334 public static function now($tz = null)
335 {
336 return new static(null, $tz);
337 }
338
339 /**
340 * Create a Carbon instance for today.
341 *
342 * @param \DateTimeZone|string|null $tz
343 *
344 * @return static
345 */
346 public static function today($tz = null)
347 {
348 return static::now($tz)->startOfDay();
349 }
350
351 /**
352 * Create a Carbon instance for tomorrow.
353 *
354 * @param \DateTimeZone|string|null $tz
355 *
356 * @return static
357 */
358 public static function tomorrow($tz = null)
359 {
360 return static::today($tz)->addDay();
361 }
362
363 /**
364 * Create a Carbon instance for yesterday.
365 *
366 * @param \DateTimeZone|string|null $tz
367 *
368 * @return static
369 */
370 public static function yesterday($tz = null)
371 {
372 return static::today($tz)->subDay();
373 }
374
375 /**
376 * Create a Carbon instance for the greatest supported date.
377 *
378 * @return static
379 */
380 public static function maxValue()
381 {
382 if (PHP_INT_SIZE === 4) {
383 // 32 bit (and additionally Windows 64 bit)
384 return static::createFromTimestamp(PHP_INT_MAX);
385 }
386
387 // 64 bit
388 return static::create(9999, 12, 31, 23, 59, 59);
389 }
390
391 /**
392 * Create a Carbon instance for the lowest supported date.
393 *
394 * @return static
395 */
396 public static function minValue()
397 {
398 if (PHP_INT_SIZE === 4) {
399 // 32 bit (and additionally Windows 64 bit)
400 return static::createFromTimestamp(~PHP_INT_MAX);
401 }
402
403 // 64 bit
404 return static::create(1, 1, 1, 0, 0, 0);
405 }
406
407 /**
408 * Create a new Carbon instance from a specific date and time.
409 *
410 * If any of $year, $month or $day are set to null their now() values will
411 * be used.
412 *
413 * If $hour is null it will be set to its now() value and the default
414 * values for $minute and $second will be their now() values.
415 *
416 * If $hour is not null then the default values for $minute and $second
417 * will be 0.
418 *
419 * @param int|null $year
420 * @param int|null $month
421 * @param int|null $day
422 * @param int|null $hour
423 * @param int|null $minute
424 * @param int|null $second
425 * @param \DateTimeZone|string|null $tz
426 *
427 * @return static
428 */
429 public static function create($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
430 {
431 $now = static::hasTestNow() ? static::getTestNow()->getTimestamp() : time();
432
433 $defaults = array_combine(array(
434 'year',
435 'month',
436 'day',
437 'hour',
438 'minute',
439 'second',
440 ), explode('-', date('Y-n-j-G-i-s', $now)));
441
442 $year = $year === null ? $defaults['year'] : $year;
443 $month = $month === null ? $defaults['month'] : $month;
444 $day = $day === null ? $defaults['day'] : $day;
445
446 if ($hour === null) {
447 $hour = $defaults['hour'];
448 $minute = $minute === null ? $defaults['minute'] : $minute;
449 $second = $second === null ? $defaults['second'] : $second;
450 } else {
451 $minute = $minute === null ? 0 : $minute;
452 $second = $second === null ? 0 : $second;
453 }
454
455 $fixYear = null;
456
457 if ($year < 0) {
458 $fixYear = $year;
459 $year = 0;
460 } elseif ($year > 9999) {
461 $fixYear = $year - 9999;
462 $year = 9999;
463 }
464
465 $instance = static::createFromFormat('Y-n-j G:i:s', sprintf('%s-%s-%s %s:%02s:%02s', $year, $month, $day, $hour, $minute, $second), $tz);
466
467 if ($fixYear !== null) {
468 $instance->addYears($fixYear);
469 }
470
471 return $instance;
472 }
473
474 /**
475 * Create a new safe Carbon instance from a specific date and time.
476 *
477 * If any of $year, $month or $day are set to null their now() values will
478 * be used.
479 *
480 * If $hour is null it will be set to its now() value and the default
481 * values for $minute and $second will be their now() values.
482 *
483 * If $hour is not null then the default values for $minute and $second
484 * will be 0.
485 *
486 * If one of the set values is not valid, an \InvalidArgumentException
487 * will be thrown.
488 *
489 * @param int|null $year
490 * @param int|null $month
491 * @param int|null $day
492 * @param int|null $hour
493 * @param int|null $minute
494 * @param int|null $second
495 * @param \DateTimeZone|string|null $tz
496 *
497 * @throws \Carbon\Exceptions\InvalidDateException
498 *
499 * @return static
500 */
501 public static function createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
502 {
503 $fields = array(
504 'year' => array(0, 9999),
505 'month' => array(0, 12),
506 'day' => array(0, 31),
507 'hour' => array(0, 24),
508 'minute' => array(0, 59),
509 'second' => array(0, 59),
510 );
511
512 foreach ($fields as $field => $range) {
513 if ($$field !== null && (!is_int($$field) || $$field < $range[0] || $$field > $range[1])) {
514 throw new InvalidDateException($field, $$field);
515 }
516 }
517
518 $instance = static::create($year, $month, 1, $hour, $minute, $second, $tz);
519
520 if ($day !== null && $day > $instance->daysInMonth) {
521 throw new InvalidDateException('day', $day);
522 }
523
524 return $instance->day($day);
525 }
526
527 /**
528 * Create a Carbon instance from just a date. The time portion is set to now.
529 *
530 * @param int|null $year
531 * @param int|null $month
532 * @param int|null $day
533 * @param \DateTimeZone|string|null $tz
534 *
535 * @return static
536 */
537 public static function createFromDate($year = null, $month = null, $day = null, $tz = null)
538 {
539 return static::create($year, $month, $day, null, null, null, $tz);
540 }
541
542 /**
543 * Create a Carbon instance from just a time. The date portion is set to today.
544 *
545 * @param int|null $hour
546 * @param int|null $minute
547 * @param int|null $second
548 * @param \DateTimeZone|string|null $tz
549 *
550 * @return static
551 */
552 public static function createFromTime($hour = null, $minute = null, $second = null, $tz = null)
553 {
554 return static::create(null, null, null, $hour, $minute, $second, $tz);
555 }
556
557 /**
558 * Create a Carbon instance from a specific format.
559 *
560 * @param string $format
561 * @param string $time
562 * @param \DateTimeZone|string|null $tz
563 *
564 * @throws \InvalidArgumentException
565 *
566 * @return static
567 */
568 public static function createFromFormat($format, $time, $tz = null)
569 {
570 if ($tz !== null) {
571 $dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz));
572 } else {
573 $dt = parent::createFromFormat($format, $time);
574 }
575
576 static::setLastErrors($lastErrors = parent::getLastErrors());
577
578 if ($dt instanceof DateTime) {
579 return static::instance($dt);
580 }
581
582 throw new InvalidArgumentException(implode(PHP_EOL, $lastErrors['errors']));
583 }
584
585 /**
586 * Set last errors.
587 *
588 * @param array $lastErrors
589 *
590 * @return void
591 */
592 private static function setLastErrors(array $lastErrors)
593 {
594 static::$lastErrors = $lastErrors;
595 }
596
597 /**
598 * {@inheritdoc}
599 */
600 public static function getLastErrors()
601 {
602 return static::$lastErrors;
603 }
604
605 /**
606 * Create a Carbon instance from a timestamp.
607 *
608 * @param int $timestamp
609 * @param \DateTimeZone|string|null $tz
610 *
611 * @return static
612 */
613 public static function createFromTimestamp($timestamp, $tz = null)
614 {
615 return static::now($tz)->setTimestamp($timestamp);
616 }
617
618 /**
619 * Create a Carbon instance from an UTC timestamp.
620 *
621 * @param int $timestamp
622 *
623 * @return static
624 */
625 public static function createFromTimestampUTC($timestamp)
626 {
627 return new static('@'.$timestamp);
628 }
629
630 /**
631 * Get a copy of the instance.
632 *
633 * @return static
634 */
635 public function copy()
636 {
637 return clone $this;
638 }
639
640 ///////////////////////////////////////////////////////////////////
641 ///////////////////////// GETTERS AND SETTERS /////////////////////
642 ///////////////////////////////////////////////////////////////////
643
644 /**
645 * Get a part of the Carbon object
646 *
647 * @param string $name
648 *
649 * @throws \InvalidArgumentException
650 *
651 * @return string|int|\DateTimeZone
652 */
653 public function __get($name)
654 {
655 switch (true) {
656 case array_key_exists($name, $formats = array(
657 'year' => 'Y',
658 'yearIso' => 'o',
659 'month' => 'n',
660 'day' => 'j',
661 'hour' => 'G',
662 'minute' => 'i',
663 'second' => 's',
664 'micro' => 'u',
665 'dayOfWeek' => 'w',
666 'dayOfYear' => 'z',
667 'weekOfYear' => 'W',
668 'daysInMonth' => 't',
669 'timestamp' => 'U',
670 )):
671 return (int) $this->format($formats[$name]);
672
673 case $name === 'weekOfMonth':
674 return (int) ceil($this->day / static::DAYS_PER_WEEK);
675
676 case $name === 'age':
677 return $this->diffInYears();
678
679 case $name === 'quarter':
680 return (int) ceil($this->month / static::MONTHS_PER_QUARTER);
681
682 case $name === 'offset':
683 return $this->getOffset();
684
685 case $name === 'offsetHours':
686 return $this->getOffset() / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR;
687
688 case $name === 'dst':
689 return $this->format('I') === '1';
690
691 case $name === 'local':
692 return $this->getOffset() === $this->copy()->setTimezone(date_default_timezone_get())->getOffset();
693
694 case $name === 'utc':
695 return $this->getOffset() === 0;
696
697 case $name === 'timezone' || $name === 'tz':
698 return $this->getTimezone();
699
700 case $name === 'timezoneName' || $name === 'tzName':
701 return $this->getTimezone()->getName();
702
703 default:
704 throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name));
705 }
706 }
707
708 /**
709 * Check if an attribute exists on the object
710 *
711 * @param string $name
712 *
713 * @return bool
714 */
715 public function __isset($name)
716 {
717 try {
718 $this->__get($name);
719 } catch (InvalidArgumentException $e) {
720 return false;
721 }
722
723 return true;
724 }
725
726 /**
727 * Set a part of the Carbon object
728 *
729 * @param string $name
730 * @param string|int|\DateTimeZone $value
731 *
732 * @throws \InvalidArgumentException
733 */
734 public function __set($name, $value)
735 {
736 switch ($name) {
737 case 'year':
738 case 'month':
739 case 'day':
740 case 'hour':
741 case 'minute':
742 case 'second':
743 list($year, $month, $day, $hour, $minute, $second) = explode('-', $this->format('Y-n-j-G-i-s'));
744 $$name = $value;
745 $this->setDateTime($year, $month, $day, $hour, $minute, $second);
746 break;
747
748 case 'timestamp':
749 parent::setTimestamp($value);
750 break;
751
752 case 'timezone':
753 case 'tz':
754 $this->setTimezone($value);
755 break;
756
757 default:
758 throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name));
759 }
760 }
761
762 /**
763 * Set the instance's year
764 *
765 * @param int $value
766 *
767 * @return static
768 */
769 public function year($value)
770 {
771 $this->year = $value;
772
773 return $this;
774 }
775
776 /**
777 * Set the instance's month
778 *
779 * @param int $value
780 *
781 * @return static
782 */
783 public function month($value)
784 {
785 $this->month = $value;
786
787 return $this;
788 }
789
790 /**
791 * Set the instance's day
792 *
793 * @param int $value
794 *
795 * @return static
796 */
797 public function day($value)
798 {
799 $this->day = $value;
800
801 return $this;
802 }
803
804 /**
805 * Set the instance's hour
806 *
807 * @param int $value
808 *
809 * @return static
810 */
811 public function hour($value)
812 {
813 $this->hour = $value;
814
815 return $this;
816 }
817
818 /**
819 * Set the instance's minute
820 *
821 * @param int $value
822 *
823 * @return static
824 */
825 public function minute($value)
826 {
827 $this->minute = $value;
828
829 return $this;
830 }
831
832 /**
833 * Set the instance's second
834 *
835 * @param int $value
836 *
837 * @return static
838 */
839 public function second($value)
840 {
841 $this->second = $value;
842
843 return $this;
844 }
845
846 /**
847 * Sets the current date of the DateTime object to a different date.
848 * Calls modify as a workaround for a php bug
849 *
850 * @param int $year
851 * @param int $month
852 * @param int $day
853 *
854 * @return static
855 *
856 * @see https://github.com/briannesbitt/Carbon/issues/539
857 * @see https://bugs.php.net/bug.php?id=63863
858 */
859 public function setDate($year, $month, $day)
860 {
861 $this->modify('+0 day');
862
863 return parent::setDate($year, $month, $day);
864 }
865
866 /**
867 * Set the date and time all together
868 *
869 * @param int $year
870 * @param int $month
871 * @param int $day
872 * @param int $hour
873 * @param int $minute
874 * @param int $second
875 *
876 * @return static
877 */
878 public function setDateTime($year, $month, $day, $hour, $minute, $second = 0)
879 {
880 return $this->setDate($year, $month, $day)->setTime($hour, $minute, $second);
881 }
882
883 /**
884 * Set the time by time string
885 *
886 * @param string $time
887 *
888 * @return static
889 */
890 public function setTimeFromTimeString($time)
891 {
892 $time = explode(':', $time);
893
894 $hour = $time[0];
895 $minute = isset($time[1]) ? $time[1] : 0;
896 $second = isset($time[2]) ? $time[2] : 0;
897
898 return $this->setTime($hour, $minute, $second);
899 }
900
901 /**
902 * Set the instance's timestamp
903 *
904 * @param int $value
905 *
906 * @return static
907 */
908 public function timestamp($value)
909 {
910 return $this->setTimestamp($value);
911 }
912
913 /**
914 * Alias for setTimezone()
915 *
916 * @param \DateTimeZone|string $value
917 *
918 * @return static
919 */
920 public function timezone($value)
921 {
922 return $this->setTimezone($value);
923 }
924
925 /**
926 * Alias for setTimezone()
927 *
928 * @param \DateTimeZone|string $value
929 *
930 * @return static
931 */
932 public function tz($value)
933 {
934 return $this->setTimezone($value);
935 }
936
937 /**
938 * Set the instance's timezone from a string or object
939 *
940 * @param \DateTimeZone|string $value
941 *
942 * @return static
943 */
944 public function setTimezone($value)
945 {
946 return parent::setTimezone(static::safeCreateDateTimeZone($value));
947 }
948
949 /**
950 * Get the days of the week
951 *
952 * @return array
953 */
954 public static function getDays()
955 {
956 return static::$days;
957 }
958
959 ///////////////////////////////////////////////////////////////////
960 /////////////////////// WEEK SPECIAL DAYS /////////////////////////
961 ///////////////////////////////////////////////////////////////////
962
963 /**
964 * Get the first day of week
965 *
966 * @return int
967 */
968 public static function getWeekStartsAt()
969 {
970 return static::$weekStartsAt;
971 }
972
973 /**
974 * Set the first day of week
975 *
976 * @param int
977 */
978 public static function setWeekStartsAt($day)
979 {
980 static::$weekStartsAt = $day;
981 }
982
983 /**
984 * Get the last day of week
985 *
986 * @return int
987 */
988 public static function getWeekEndsAt()
989 {
990 return static::$weekEndsAt;
991 }
992
993 /**
994 * Set the last day of week
995 *
996 * @param int
997 */
998 public static function setWeekEndsAt($day)
999 {
1000 static::$weekEndsAt = $day;
1001 }
1002
1003 /**
1004 * Get weekend days
1005 *
1006 * @return array
1007 */
1008 public static function getWeekendDays()
1009 {
1010 return static::$weekendDays;
1011 }
1012
1013 /**
1014 * Set weekend days
1015 *
1016 * @param array
1017 */
1018 public static function setWeekendDays($days)
1019 {
1020 static::$weekendDays = $days;
1021 }
1022
1023 ///////////////////////////////////////////////////////////////////
1024 ///////////////////////// TESTING AIDS ////////////////////////////
1025 ///////////////////////////////////////////////////////////////////
1026
1027 /**
1028 * Set a Carbon instance (real or mock) to be returned when a "now"
1029 * instance is created. The provided instance will be returned
1030 * specifically under the following conditions:
1031 * - A call to the static now() method, ex. Carbon::now()
1032 * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
1033 * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
1034 * - When a string containing the desired time is passed to Carbon::parse().
1035 *
1036 * Note the timezone parameter was left out of the examples above and
1037 * has no affect as the mock value will be returned regardless of its value.
1038 *
1039 * To clear the test instance call this method using the default
1040 * parameter of null.
1041 *
1042 * @param \Carbon\Carbon|string|null $testNow
1043 */
1044 public static function setTestNow($testNow = null)
1045 {
1046 static::$testNow = is_string($testNow) ? static::parse($testNow) : $testNow;
1047 }
1048
1049 /**
1050 * Get the Carbon instance (real or mock) to be returned when a "now"
1051 * instance is created.
1052 *
1053 * @return static the current instance used for testing
1054 */
1055 public static function getTestNow()
1056 {
1057 return static::$testNow;
1058 }
1059
1060 /**
1061 * Determine if there is a valid test instance set. A valid test instance
1062 * is anything that is not null.
1063 *
1064 * @return bool true if there is a test instance, otherwise false
1065 */
1066 public static function hasTestNow()
1067 {
1068 return static::getTestNow() !== null;
1069 }
1070
1071 /**
1072 * Determine if there is a relative keyword in the time string, this is to
1073 * create dates relative to now for test instances. e.g.: next tuesday
1074 *
1075 * @param string $time
1076 *
1077 * @return bool true if there is a keyword, otherwise false
1078 */
1079 public static function hasRelativeKeywords($time)
1080 {
1081 // skip common format with a '-' in it
1082 if (preg_match('/\d{4}-\d{1,2}-\d{1,2}/', $time) !== 1) {
1083 foreach (static::$relativeKeywords as $keyword) {
1084 if (stripos($time, $keyword) !== false) {
1085 return true;
1086 }
1087 }
1088 }
1089
1090 return false;
1091 }
1092
1093 ///////////////////////////////////////////////////////////////////
1094 /////////////////////// LOCALIZATION //////////////////////////////
1095 ///////////////////////////////////////////////////////////////////
1096
1097 /**
1098 * Initialize the translator instance if necessary.
1099 *
1100 * @return \Symfony\Component\Translation\TranslatorInterface
1101 */
1102 protected static function translator()
1103 {
1104 if (static::$translator === null) {
1105 $translator = new Translator('en');
1106 $translator->addLoader('array', new ArrayLoader());
1107 static::$translator = $translator;
1108 static::setLocale('en');
1109 }
1110
1111 return static::$translator;
1112 }
1113
1114 /**
1115 * Get the translator instance in use
1116 *
1117 * @return \Symfony\Component\Translation\TranslatorInterface
1118 */
1119 public static function getTranslator()
1120 {
1121 return static::translator();
1122 }
1123
1124 /**
1125 * Set the translator instance to use
1126 *
1127 * @param \Symfony\Component\Translation\TranslatorInterface $translator
1128 */
1129 public static function setTranslator(TranslatorInterface $translator)
1130 {
1131 static::$translator = $translator;
1132 }
1133
1134 /**
1135 * Get the current translator locale
1136 *
1137 * @return string
1138 */
1139 public static function getLocale()
1140 {
1141 return static::translator()->getLocale();
1142 }
1143
1144 /**
1145 * Set the current translator locale and indicate if the source locale file exists
1146 *
1147 * @param string $locale
1148 *
1149 * @return bool
1150 */
1151 public static function setLocale($locale)
1152 {
1153 $locale = preg_replace_callback('/\b([a-z]{2})[-_](?:([a-z]{4})[-_])?([a-z]{2})\b/', function ($matches) {
1154 return $matches[1].'_'.(!empty($matches[2]) ? ucfirst($matches[2]).'_' : '').strtoupper($matches[3]);
1155 }, strtolower($locale));
1156
1157 if (file_exists($filename = __DIR__.'/Lang/'.$locale.'.php')) {
1158 $translator = static::translator();
1159 $translator->setLocale($locale);
1160
1161 if ($translator instanceof Translator) {
1162 // Ensure the locale has been loaded.
1163 $translator->addResource('array', require $filename, $locale);
1164 }
1165
1166 return true;
1167 }
1168
1169 return false;
1170 }
1171
1172 ///////////////////////////////////////////////////////////////////
1173 /////////////////////// STRING FORMATTING /////////////////////////
1174 ///////////////////////////////////////////////////////////////////
1175
1176 /**
1177 * Set if UTF8 will be used for localized date/time
1178 *
1179 * @param bool $utf8
1180 */
1181 public static function setUtf8($utf8)
1182 {
1183 static::$utf8 = $utf8;
1184 }
1185
1186 /**
1187 * Format the instance with the current locale. You can set the current
1188 * locale using setlocale() http://php.net/setlocale.
1189 *
1190 * @param string $format
1191 *
1192 * @return string
1193 */
1194 public function formatLocalized($format)
1195 {
1196 // Check for Windows to find and replace the %e
1197 // modifier correctly
1198 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
1199 $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format);
1200 }
1201
1202 $formatted = strftime($format, strtotime($this));
1203
1204 return static::$utf8 ? utf8_encode($formatted) : $formatted;
1205 }
1206
1207 /**
1208 * Reset the format used to the default when type juggling a Carbon instance to a string
1209 */
1210 public static function resetToStringFormat()
1211 {
1212 static::setToStringFormat(static::DEFAULT_TO_STRING_FORMAT);
1213 }
1214
1215 /**
1216 * Set the default format used when type juggling a Carbon instance to a string
1217 *
1218 * @param string $format
1219 */
1220 public static function setToStringFormat($format)
1221 {
1222 static::$toStringFormat = $format;
1223 }
1224
1225 /**
1226 * Format the instance as a string using the set format
1227 *
1228 * @return string
1229 */
1230 public function __toString()
1231 {
1232 return $this->format(static::$toStringFormat);
1233 }
1234
1235 /**
1236 * Format the instance as date
1237 *
1238 * @return string
1239 */
1240 public function toDateString()
1241 {
1242 return $this->format('Y-m-d');
1243 }
1244
1245 /**
1246 * Format the instance as a readable date
1247 *
1248 * @return string
1249 */
1250 public function toFormattedDateString()
1251 {
1252 return $this->format('M j, Y');
1253 }
1254
1255 /**
1256 * Format the instance as time
1257 *
1258 * @return string
1259 */
1260 public function toTimeString()
1261 {
1262 return $this->format('H:i:s');
1263 }
1264
1265 /**
1266 * Format the instance as date and time
1267 *
1268 * @return string
1269 */
1270 public function toDateTimeString()
1271 {
1272 return $this->format('Y-m-d H:i:s');
1273 }
1274
1275 /**
1276 * Format the instance with day, date and time
1277 *
1278 * @return string
1279 */
1280 public function toDayDateTimeString()
1281 {
1282 return $this->format('D, M j, Y g:i A');
1283 }
1284
1285 /**
1286 * Format the instance as ATOM
1287 *
1288 * @return string
1289 */
1290 public function toAtomString()
1291 {
1292 return $this->format(static::ATOM);
1293 }
1294
1295 /**
1296 * Format the instance as COOKIE
1297 *
1298 * @return string
1299 */
1300 public function toCookieString()
1301 {
1302 return $this->format(static::COOKIE);
1303 }
1304
1305 /**
1306 * Format the instance as ISO8601
1307 *
1308 * @return string
1309 */
1310 public function toIso8601String()
1311 {
1312 return $this->toAtomString();
1313 }
1314
1315 /**
1316 * Format the instance as RFC822
1317 *
1318 * @return string
1319 */
1320 public function toRfc822String()
1321 {
1322 return $this->format(static::RFC822);
1323 }
1324
1325 /**
1326 * Format the instance as RFC850
1327 *
1328 * @return string
1329 */
1330 public function toRfc850String()
1331 {
1332 return $this->format(static::RFC850);
1333 }
1334
1335 /**
1336 * Format the instance as RFC1036
1337 *
1338 * @return string
1339 */
1340 public function toRfc1036String()
1341 {
1342 return $this->format(static::RFC1036);
1343 }
1344
1345 /**
1346 * Format the instance as RFC1123
1347 *
1348 * @return string
1349 */
1350 public function toRfc1123String()
1351 {
1352 return $this->format(static::RFC1123);
1353 }
1354
1355 /**
1356 * Format the instance as RFC2822
1357 *
1358 * @return string
1359 */
1360 public function toRfc2822String()
1361 {
1362 return $this->format(static::RFC2822);
1363 }
1364
1365 /**
1366 * Format the instance as RFC3339
1367 *
1368 * @return string
1369 */
1370 public function toRfc3339String()
1371 {
1372 return $this->format(static::RFC3339);
1373 }
1374
1375 /**
1376 * Format the instance as RSS
1377 *
1378 * @return string
1379 */
1380 public function toRssString()
1381 {
1382 return $this->format(static::RSS);
1383 }
1384
1385 /**
1386 * Format the instance as W3C
1387 *
1388 * @return string
1389 */
1390 public function toW3cString()
1391 {
1392 return $this->format(static::W3C);
1393 }
1394
1395 ///////////////////////////////////////////////////////////////////
1396 ////////////////////////// COMPARISONS ////////////////////////////
1397 ///////////////////////////////////////////////////////////////////
1398
1399 /**
1400 * Determines if the instance is equal to another
1401 *
1402 * @param Carbon $dt
1403 *
1404 * @return bool
1405 */
1406 public function eq(Carbon $dt)
1407 {
1408 return $this == $dt;
1409 }
1410
1411 /**
1412 * Determines if the instance is equal to another
1413 *
1414 * @param Carbon $dt
1415 *
1416 * @see eq()
1417 *
1418 * @return bool
1419 */
1420 public function equalTo(Carbon $dt)
1421 {
1422 return $this->eq($dt);
1423 }
1424
1425 /**
1426 * Determines if the instance is not equal to another
1427 *
1428 * @param Carbon $dt
1429 *
1430 * @return bool
1431 */
1432 public function ne(Carbon $dt)
1433 {
1434 return !$this->eq($dt);
1435 }
1436
1437 /**
1438 * Determines if the instance is not equal to another
1439 *
1440 * @param Carbon $dt
1441 *
1442 * @see ne()
1443 *
1444 * @return bool
1445 */
1446 public function notEqualTo(Carbon $dt)
1447 {
1448 return $this->ne($dt);
1449 }
1450
1451 /**
1452 * Determines if the instance is greater (after) than another
1453 *
1454 * @param Carbon $dt
1455 *
1456 * @return bool
1457 */
1458 public function gt(Carbon $dt)
1459 {
1460 return $this > $dt;
1461 }
1462
1463 /**
1464 * Determines if the instance is greater (after) than another
1465 *
1466 * @param Carbon $dt
1467 *
1468 * @see gt()
1469 *
1470 * @return bool
1471 */
1472 public function greaterThan(Carbon $dt)
1473 {
1474 return $this->gt($dt);
1475 }
1476
1477 /**
1478 * Determines if the instance is greater (after) than or equal to another
1479 *
1480 * @param Carbon $dt
1481 *
1482 * @return bool
1483 */
1484 public function gte(Carbon $dt)
1485 {
1486 return $this >= $dt;
1487 }
1488
1489 /**
1490 * Determines if the instance is greater (after) than or equal to another
1491 *
1492 * @param Carbon $dt
1493 *
1494 * @see gte()
1495 *
1496 * @return bool
1497 */
1498 public function greaterThanOrEqualTo(Carbon $dt)
1499 {
1500 return $this->gte($dt);
1501 }
1502
1503 /**
1504 * Determines if the instance is less (before) than another
1505 *
1506 * @param Carbon $dt
1507 *
1508 * @return bool
1509 */
1510 public function lt(Carbon $dt)
1511 {
1512 return $this < $dt;
1513 }
1514
1515 /**
1516 * Determines if the instance is less (before) than another
1517 *
1518 * @param Carbon $dt
1519 *
1520 * @see lt()
1521 *
1522 * @return bool
1523 */
1524 public function lessThan(Carbon $dt)
1525 {
1526 return $this->lt($dt);
1527 }
1528
1529 /**
1530 * Determines if the instance is less (before) or equal to another
1531 *
1532 * @param Carbon $dt
1533 *
1534 * @return bool
1535 */
1536 public function lte(Carbon $dt)
1537 {
1538 return $this <= $dt;
1539 }
1540
1541 /**
1542 * Determines if the instance is less (before) or equal to another
1543 *
1544 * @param Carbon $dt
1545 *
1546 * @see lte()
1547 *
1548 * @return bool
1549 */
1550 public function lessThanOrEqualTo(Carbon $dt)
1551 {
1552 return $this->lte($dt);
1553 }
1554
1555 /**
1556 * Determines if the instance is between two others
1557 *
1558 * @param Carbon $dt1
1559 * @param Carbon $dt2
1560 * @param bool $equal Indicates if a > and < comparison should be used or <= or >=
1561 *
1562 * @return bool
1563 */
1564 public function between(Carbon $dt1, Carbon $dt2, $equal = true)
1565 {
1566 if ($dt1->gt($dt2)) {
1567 $temp = $dt1;
1568 $dt1 = $dt2;
1569 $dt2 = $temp;
1570 }
1571
1572 if ($equal) {
1573 return $this->gte($dt1) && $this->lte($dt2);
1574 }
1575
1576 return $this->gt($dt1) && $this->lt($dt2);
1577 }
1578
1579 /**
1580 * Get the closest date from the instance.
1581 *
1582 * @param Carbon $dt1
1583 * @param Carbon $dt2
1584 *
1585 * @return static
1586 */
1587 public function closest(Carbon $dt1, Carbon $dt2)
1588 {
1589 return $this->diffInSeconds($dt1) < $this->diffInSeconds($dt2) ? $dt1 : $dt2;
1590 }
1591
1592 /**
1593 * Get the farthest date from the instance.
1594 *
1595 * @param Carbon $dt1
1596 * @param Carbon $dt2
1597 *
1598 * @return static
1599 */
1600 public function farthest(Carbon $dt1, Carbon $dt2)
1601 {
1602 return $this->diffInSeconds($dt1) > $this->diffInSeconds($dt2) ? $dt1 : $dt2;
1603 }
1604
1605 /**
1606 * Get the minimum instance between a given instance (default now) and the current instance.
1607 *
1608 * @param \Carbon\Carbon|null $dt
1609 *
1610 * @return static
1611 */
1612 public function min(Carbon $dt = null)
1613 {
1614 $dt = $dt ?: static::now($this->getTimezone());
1615
1616 return $this->lt($dt) ? $this : $dt;
1617 }
1618
1619 /**
1620 * Get the minimum instance between a given instance (default now) and the current instance.
1621 *
1622 * @param \Carbon\Carbon|null $dt
1623 *
1624 * @see min()
1625 *
1626 * @return static
1627 */
1628 public function minimum(Carbon $dt = null)
1629 {
1630 return $this->min($dt);
1631 }
1632
1633 /**
1634 * Get the maximum instance between a given instance (default now) and the current instance.
1635 *
1636 * @param \Carbon\Carbon|null $dt
1637 *
1638 * @return static
1639 */
1640 public function max(Carbon $dt = null)
1641 {
1642 $dt = $dt ?: static::now($this->getTimezone());
1643
1644 return $this->gt($dt) ? $this : $dt;
1645 }
1646
1647 /**
1648 * Get the maximum instance between a given instance (default now) and the current instance.
1649 *
1650 * @param \Carbon\Carbon|null $dt
1651 *
1652 * @see max()
1653 *
1654 * @return static
1655 */
1656 public function maximum(Carbon $dt = null)
1657 {
1658 return $this->max($dt);
1659 }
1660
1661 /**
1662 * Determines if the instance is a weekday
1663 *
1664 * @return bool
1665 */
1666 public function isWeekday()
1667 {
1668 return !$this->isWeekend();
1669 }
1670
1671 /**
1672 * Determines if the instance is a weekend day
1673 *
1674 * @return bool
1675 */
1676 public function isWeekend()
1677 {
1678 return in_array($this->dayOfWeek, static::$weekendDays);
1679 }
1680
1681 /**
1682 * Determines if the instance is yesterday
1683 *
1684 * @return bool
1685 */
1686 public function isYesterday()
1687 {
1688 return $this->toDateString() === static::yesterday($this->getTimezone())->toDateString();
1689 }
1690
1691 /**
1692 * Determines if the instance is today
1693 *
1694 * @return bool
1695 */
1696 public function isToday()
1697 {
1698 return $this->toDateString() === static::now($this->getTimezone())->toDateString();
1699 }
1700
1701 /**
1702 * Determines if the instance is tomorrow
1703 *
1704 * @return bool
1705 */
1706 public function isTomorrow()
1707 {
1708 return $this->toDateString() === static::tomorrow($this->getTimezone())->toDateString();
1709 }
1710
1711 /**
1712 * Determines if the instance is within the next week
1713 *
1714 * @return bool
1715 */
1716 public function isNextWeek()
1717 {
1718 return $this->weekOfYear === static::now($this->getTimezone())->addWeek()->weekOfYear;
1719 }
1720
1721 /**
1722 * Determines if the instance is within the last week
1723 *
1724 * @return bool
1725 */
1726 public function isLastWeek()
1727 {
1728 return $this->weekOfYear === static::now($this->getTimezone())->subWeek()->weekOfYear;
1729 }
1730
1731 /**
1732 * Determines if the instance is within the next month
1733 *
1734 * @return bool
1735 */
1736 public function isNextMonth()
1737 {
1738 return $this->month === static::now($this->getTimezone())->addMonthNoOverflow()->month;
1739 }
1740
1741 /**
1742 * Determines if the instance is within the last month
1743 *
1744 * @return bool
1745 */
1746 public function isLastMonth()
1747 {
1748 return $this->month === static::now($this->getTimezone())->subMonthNoOverflow()->month;
1749 }
1750
1751 /**
1752 * Determines if the instance is within next year
1753 *
1754 * @return bool
1755 */
1756 public function isNextYear()
1757 {
1758 return $this->year === static::now($this->getTimezone())->addYear()->year;
1759 }
1760
1761 /**
1762 * Determines if the instance is within the previous year
1763 *
1764 * @return bool
1765 */
1766 public function isLastYear()
1767 {
1768 return $this->year === static::now($this->getTimezone())->subYear()->year;
1769 }
1770
1771 /**
1772 * Determines if the instance is in the future, ie. greater (after) than now
1773 *
1774 * @return bool
1775 */
1776 public function isFuture()
1777 {
1778 return $this->gt(static::now($this->getTimezone()));
1779 }
1780
1781 /**
1782 * Determines if the instance is in the past, ie. less (before) than now
1783 *
1784 * @return bool
1785 */
1786 public function isPast()
1787 {
1788 return $this->lt(static::now($this->getTimezone()));
1789 }
1790
1791 /**
1792 * Determines if the instance is a leap year
1793 *
1794 * @return bool
1795 */
1796 public function isLeapYear()
1797 {
1798 return $this->format('L') === '1';
1799 }
1800
1801 /**
1802 * Determines if the instance is a long year
1803 *
1804 * @see https://en.wikipedia.org/wiki/ISO_8601#Week_dates
1805 *
1806 * @return bool
1807 */
1808 public function isLongYear()
1809 {
1810 return static::create($this->year, 12, 28, 0, 0, 0, $this->tz)->weekOfYear === 53;
1811 }
1812
1813 /*
1814 * Compares the formatted values of the two dates.
1815 *
1816 * @param string $format The date formats to compare.
1817 * @param \Carbon\Carbon|null $dt The instance to compare with or null to use current day.
1818 *
1819 * @return bool
1820 */
1821 public function isSameAs($format, Carbon $dt = null)
1822 {
1823 $dt = $dt ?: static::now($this->tz);
1824
1825 return $this->format($format) === $dt->format($format);
1826 }
1827
1828 /**
1829 * Determines if the instance is in the current year
1830 *
1831 * @return bool
1832 */
1833 public function isCurrentYear()
1834 {
1835 return $this->isSameYear();
1836 }
1837
1838 /**
1839 * Checks if the passed in date is in the same year as the instance year.
1840 *
1841 * @param \Carbon\Carbon|null $dt The instance to compare with or null to use current day.
1842 *
1843 * @return bool
1844 */
1845 public function isSameYear(Carbon $dt = null)
1846 {
1847 return $this->isSameAs('Y', $dt);
1848 }
1849
1850 /**
1851 * Determines if the instance is in the current month
1852 *
1853 * @return bool
1854 */
1855 public function isCurrentMonth()
1856 {
1857 return $this->isSameMonth();
1858 }
1859
1860 /**
1861 * Checks if the passed in date is in the same month as the instance month (and year if needed).
1862 *
1863 * @param \Carbon\Carbon|null $dt The instance to compare with or null to use current day.
1864 * @param bool $ofSameYear Check if it is the same month in the same year.
1865 *
1866 * @return bool
1867 */
1868 public function isSameMonth(Carbon $dt = null, $ofSameYear = false)
1869 {
1870 $format = $ofSameYear ? 'Y-m' : 'm';
1871
1872 return $this->isSameAs($format, $dt);
1873 }
1874
1875 /**
1876 * Checks if the passed in date is the same day as the instance current day.
1877 *
1878 * @param \Carbon\Carbon $dt
1879 *
1880 * @return bool
1881 */
1882 public function isSameDay(Carbon $dt)
1883 {
1884 return $this->toDateString() === $dt->toDateString();
1885 }
1886
1887 /**
1888 * Checks if this day is a Sunday.
1889 *
1890 * @return bool
1891 */
1892 public function isSunday()
1893 {
1894 return $this->dayOfWeek === static::SUNDAY;
1895 }
1896
1897 /**
1898 * Checks if this day is a Monday.
1899 *
1900 * @return bool
1901 */
1902 public function isMonday()
1903 {
1904 return $this->dayOfWeek === static::MONDAY;
1905 }
1906
1907 /**
1908 * Checks if this day is a Tuesday.
1909 *
1910 * @return bool
1911 */
1912 public function isTuesday()
1913 {
1914 return $this->dayOfWeek === static::TUESDAY;
1915 }
1916
1917 /**
1918 * Checks if this day is a Wednesday.
1919 *
1920 * @return bool
1921 */
1922 public function isWednesday()
1923 {
1924 return $this->dayOfWeek === static::WEDNESDAY;
1925 }
1926
1927 /**
1928 * Checks if this day is a Thursday.
1929 *
1930 * @return bool
1931 */
1932 public function isThursday()
1933 {
1934 return $this->dayOfWeek === static::THURSDAY;
1935 }
1936
1937 /**
1938 * Checks if this day is a Friday.
1939 *
1940 * @return bool
1941 */
1942 public function isFriday()
1943 {
1944 return $this->dayOfWeek === static::FRIDAY;
1945 }
1946
1947 /**
1948 * Checks if this day is a Saturday.
1949 *
1950 * @return bool
1951 */
1952 public function isSaturday()
1953 {
1954 return $this->dayOfWeek === static::SATURDAY;
1955 }
1956
1957 ///////////////////////////////////////////////////////////////////
1958 /////////////////// ADDITIONS AND SUBTRACTIONS ////////////////////
1959 ///////////////////////////////////////////////////////////////////
1960
1961 /**
1962 * Add years to the instance. Positive $value travel forward while
1963 * negative $value travel into the past.
1964 *
1965 * @param int $value
1966 *
1967 * @return static
1968 */
1969 public function addYears($value)
1970 {
1971 return $this->modify((int) $value.' year');
1972 }
1973
1974 /**
1975 * Add a year to the instance
1976 *
1977 * @param int $value
1978 *
1979 * @return static
1980 */
1981 public function addYear($value = 1)
1982 {
1983 return $this->addYears($value);
1984 }
1985
1986 /**
1987 * Remove a year from the instance
1988 *
1989 * @param int $value
1990 *
1991 * @return static
1992 */
1993 public function subYear($value = 1)
1994 {
1995 return $this->subYears($value);
1996 }
1997
1998 /**
1999 * Remove years from the instance.
2000 *
2001 * @param int $value
2002 *
2003 * @return static
2004 */
2005 public function subYears($value)
2006 {
2007 return $this->addYears(-1 * $value);
2008 }
2009
2010 /**
2011 * Add quarters to the instance. Positive $value travels forward while
2012 * negative $value travels into the past.
2013 *
2014 * @param int $value
2015 *
2016 * @return static
2017 */
2018 public function addQuarters($value)
2019 {
2020 return $this->addMonths(static::MONTHS_PER_QUARTER * $value);
2021 }
2022
2023 /**
2024 * Add a quarter to the instance
2025 *
2026 * @param int $value
2027 *
2028 * @return static
2029 */
2030 public function addQuarter($value = 1)
2031 {
2032 return $this->addQuarters($value);
2033 }
2034
2035 /**
2036 * Remove a quarter from the instance
2037 *
2038 * @param int $value
2039 *
2040 * @return static
2041 */
2042 public function subQuarter($value = 1)
2043 {
2044 return $this->subQuarters($value);
2045 }
2046
2047 /**
2048 * Remove quarters from the instance
2049 *
2050 * @param int $value
2051 *
2052 * @return static
2053 */
2054 public function subQuarters($value)
2055 {
2056 return $this->addQuarters(-1 * $value);
2057 }
2058
2059 /**
2060 * Add centuries to the instance. Positive $value travels forward while
2061 * negative $value travels into the past.
2062 *
2063 * @param int $value
2064 *
2065 * @return static
2066 */
2067 public function addCenturies($value)
2068 {
2069 return $this->addYears(static::YEARS_PER_CENTURY * $value);
2070 }
2071
2072 /**
2073 * Add a century to the instance
2074 *
2075 * @param int $value
2076 *
2077 * @return static
2078 */
2079 public function addCentury($value = 1)
2080 {
2081 return $this->addCenturies($value);
2082 }
2083
2084 /**
2085 * Remove a century from the instance
2086 *
2087 * @param int $value
2088 *
2089 * @return static
2090 */
2091 public function subCentury($value = 1)
2092 {
2093 return $this->subCenturies($value);
2094 }
2095
2096 /**
2097 * Remove centuries from the instance
2098 *
2099 * @param int $value
2100 *
2101 * @return static
2102 */
2103 public function subCenturies($value)
2104 {
2105 return $this->addCenturies(-1 * $value);
2106 }
2107
2108 /**
2109 * Add months to the instance. Positive $value travels forward while
2110 * negative $value travels into the past.
2111 *
2112 * @param int $value
2113 *
2114 * @return static
2115 */
2116 public function addMonths($value)
2117 {
2118 if (static::shouldOverflowMonths()) {
2119 return $this->addMonthsWithOverflow($value);
2120 }
2121
2122 return $this->addMonthsNoOverflow($value);
2123 }
2124
2125 /**
2126 * Add a month to the instance
2127 *
2128 * @param int $value
2129 *
2130 * @return static
2131 */
2132 public function addMonth($value = 1)
2133 {
2134 return $this->addMonths($value);
2135 }
2136
2137 /**
2138 * Remove a month from the instance
2139 *
2140 * @param int $value
2141 *
2142 * @return static
2143 */
2144 public function subMonth($value = 1)
2145 {
2146 return $this->subMonths($value);
2147 }
2148
2149 /**
2150 * Remove months from the instance
2151 *
2152 * @param int $value
2153 *
2154 * @return static
2155 */
2156 public function subMonths($value)
2157 {
2158 return $this->addMonths(-1 * $value);
2159 }
2160
2161 /**
2162 * Add months to the instance. Positive $value travels forward while
2163 * negative $value travels into the past.
2164 *
2165 * @param int $value
2166 *
2167 * @return static
2168 */
2169 public function addMonthsWithOverflow($value)
2170 {
2171 return $this->modify((int) $value.' month');
2172 }
2173
2174 /**
2175 * Add a month to the instance
2176 *
2177 * @param int $value
2178 *
2179 * @return static
2180 */
2181 public function addMonthWithOverflow($value = 1)
2182 {
2183 return $this->addMonthsWithOverflow($value);
2184 }
2185
2186 /**
2187 * Remove a month from the instance
2188 *
2189 * @param int $value
2190 *
2191 * @return static
2192 */
2193 public function subMonthWithOverflow($value = 1)
2194 {
2195 return $this->subMonthsWithOverflow($value);
2196 }
2197
2198 /**
2199 * Remove months from the instance
2200 *
2201 * @param int $value
2202 *
2203 * @return static
2204 */
2205 public function subMonthsWithOverflow($value)
2206 {
2207 return $this->addMonthsWithOverflow(-1 * $value);
2208 }
2209
2210 /**
2211 * Add months without overflowing to the instance. Positive $value
2212 * travels forward while negative $value travels into the past.
2213 *
2214 * @param int $value
2215 *
2216 * @return static
2217 */
2218 public function addMonthsNoOverflow($value)
2219 {
2220 $day = $this->day;
2221
2222 $this->modify((int) $value.' month');
2223
2224 if ($day !== $this->day) {
2225 $this->modify('last day of previous month');
2226 }
2227
2228 return $this;
2229 }
2230
2231 /**
2232 * Add a month with no overflow to the instance
2233 *
2234 * @param int $value
2235 *
2236 * @return static
2237 */
2238 public function addMonthNoOverflow($value = 1)
2239 {
2240 return $this->addMonthsNoOverflow($value);
2241 }
2242
2243 /**
2244 * Remove a month with no overflow from the instance
2245 *
2246 * @param int $value
2247 *
2248 * @return static
2249 */
2250 public function subMonthNoOverflow($value = 1)
2251 {
2252 return $this->subMonthsNoOverflow($value);
2253 }
2254
2255 /**
2256 * Remove months with no overflow from the instance
2257 *
2258 * @param int $value
2259 *
2260 * @return static
2261 */
2262 public function subMonthsNoOverflow($value)
2263 {
2264 return $this->addMonthsNoOverflow(-1 * $value);
2265 }
2266
2267 /**
2268 * Add days to the instance. Positive $value travels forward while
2269 * negative $value travels into the past.
2270 *
2271 * @param int $value
2272 *
2273 * @return static
2274 */
2275 public function addDays($value)
2276 {
2277 return $this->modify((int) $value.' day');
2278 }
2279
2280 /**
2281 * Add a day to the instance
2282 *
2283 * @param int $value
2284 *
2285 * @return static
2286 */
2287 public function addDay($value = 1)
2288 {
2289 return $this->addDays($value);
2290 }
2291
2292 /**
2293 * Remove a day from the instance
2294 *
2295 * @param int $value
2296 *
2297 * @return static
2298 */
2299 public function subDay($value = 1)
2300 {
2301 return $this->subDays($value);
2302 }
2303
2304 /**
2305 * Remove days from the instance
2306 *
2307 * @param int $value
2308 *
2309 * @return static
2310 */
2311 public function subDays($value)
2312 {
2313 return $this->addDays(-1 * $value);
2314 }
2315
2316 /**
2317 * Add weekdays to the instance. Positive $value travels forward while
2318 * negative $value travels into the past.
2319 *
2320 * @param int $value
2321 *
2322 * @return static
2323 */
2324 public function addWeekdays($value)
2325 {
2326 // fix for https://bugs.php.net/bug.php?id=54909
2327 $t = $this->toTimeString();
2328 $this->modify((int) $value.' weekday');
2329
2330 return $this->setTimeFromTimeString($t);
2331 }
2332
2333 /**
2334 * Add a weekday to the instance
2335 *
2336 * @param int $value
2337 *
2338 * @return static
2339 */
2340 public function addWeekday($value = 1)
2341 {
2342 return $this->addWeekdays($value);
2343 }
2344
2345 /**
2346 * Remove a weekday from the instance
2347 *
2348 * @param int $value
2349 *
2350 * @return static
2351 */
2352 public function subWeekday($value = 1)
2353 {
2354 return $this->subWeekdays($value);
2355 }
2356
2357 /**
2358 * Remove weekdays from the instance
2359 *
2360 * @param int $value
2361 *
2362 * @return static
2363 */
2364 public function subWeekdays($value)
2365 {
2366 return $this->addWeekdays(-1 * $value);
2367 }
2368
2369 /**
2370 * Add weeks to the instance. Positive $value travels forward while
2371 * negative $value travels into the past.
2372 *
2373 * @param int $value
2374 *
2375 * @return static
2376 */
2377 public function addWeeks($value)
2378 {
2379 return $this->modify((int) $value.' week');
2380 }
2381
2382 /**
2383 * Add a week to the instance
2384 *
2385 * @param int $value
2386 *
2387 * @return static
2388 */
2389 public function addWeek($value = 1)
2390 {
2391 return $this->addWeeks($value);
2392 }
2393
2394 /**
2395 * Remove a week from the instance
2396 *
2397 * @param int $value
2398 *
2399 * @return static
2400 */
2401 public function subWeek($value = 1)
2402 {
2403 return $this->subWeeks($value);
2404 }
2405
2406 /**
2407 * Remove weeks to the instance
2408 *
2409 * @param int $value
2410 *
2411 * @return static
2412 */
2413 public function subWeeks($value)
2414 {
2415 return $this->addWeeks(-1 * $value);
2416 }
2417
2418 /**
2419 * Add hours to the instance. Positive $value travels forward while
2420 * negative $value travels into the past.
2421 *
2422 * @param int $value
2423 *
2424 * @return static
2425 */
2426 public function addHours($value)
2427 {
2428 return $this->modify((int) $value.' hour');
2429 }
2430
2431 /**
2432 * Add an hour to the instance
2433 *
2434 * @param int $value
2435 *
2436 * @return static
2437 */
2438 public function addHour($value = 1)
2439 {
2440 return $this->addHours($value);
2441 }
2442
2443 /**
2444 * Remove an hour from the instance
2445 *
2446 * @param int $value
2447 *
2448 * @return static
2449 */
2450 public function subHour($value = 1)
2451 {
2452 return $this->subHours($value);
2453 }
2454
2455 /**
2456 * Remove hours from the instance
2457 *
2458 * @param int $value
2459 *
2460 * @return static
2461 */
2462 public function subHours($value)
2463 {
2464 return $this->addHours(-1 * $value);
2465 }
2466
2467 /**
2468 * Add minutes to the instance. Positive $value travels forward while
2469 * negative $value travels into the past.
2470 *
2471 * @param int $value
2472 *
2473 * @return static
2474 */
2475 public function addMinutes($value)
2476 {
2477 return $this->modify((int) $value.' minute');
2478 }
2479
2480 /**
2481 * Add a minute to the instance
2482 *
2483 * @param int $value
2484 *
2485 * @return static
2486 */
2487 public function addMinute($value = 1)
2488 {
2489 return $this->addMinutes($value);
2490 }
2491
2492 /**
2493 * Remove a minute from the instance
2494 *
2495 * @param int $value
2496 *
2497 * @return static
2498 */
2499 public function subMinute($value = 1)
2500 {
2501 return $this->subMinutes($value);
2502 }
2503
2504 /**
2505 * Remove minutes from the instance
2506 *
2507 * @param int $value
2508 *
2509 * @return static
2510 */
2511 public function subMinutes($value)
2512 {
2513 return $this->addMinutes(-1 * $value);
2514 }
2515
2516 /**
2517 * Add seconds to the instance. Positive $value travels forward while
2518 * negative $value travels into the past.
2519 *
2520 * @param int $value
2521 *
2522 * @return static
2523 */
2524 public function addSeconds($value)
2525 {
2526 return $this->modify((int) $value.' second');
2527 }
2528
2529 /**
2530 * Add a second to the instance
2531 *
2532 * @param int $value
2533 *
2534 * @return static
2535 */
2536 public function addSecond($value = 1)
2537 {
2538 return $this->addSeconds($value);
2539 }
2540
2541 /**
2542 * Remove a second from the instance
2543 *
2544 * @param int $value
2545 *
2546 * @return static
2547 */
2548 public function subSecond($value = 1)
2549 {
2550 return $this->subSeconds($value);
2551 }
2552
2553 /**
2554 * Remove seconds from the instance
2555 *
2556 * @param int $value
2557 *
2558 * @return static
2559 */
2560 public function subSeconds($value)
2561 {
2562 return $this->addSeconds(-1 * $value);
2563 }
2564
2565 ///////////////////////////////////////////////////////////////////
2566 /////////////////////////// DIFFERENCES ///////////////////////////
2567 ///////////////////////////////////////////////////////////////////
2568
2569 /**
2570 * Get the difference in years
2571 *
2572 * @param \Carbon\Carbon|null $dt
2573 * @param bool $abs Get the absolute of the difference
2574 *
2575 * @return int
2576 */
2577 public function diffInYears(Carbon $dt = null, $abs = true)
2578 {
2579 $dt = $dt ?: static::now($this->getTimezone());
2580
2581 return (int) $this->diff($dt, $abs)->format('%r%y');
2582 }
2583
2584 /**
2585 * Get the difference in months
2586 *
2587 * @param \Carbon\Carbon|null $dt
2588 * @param bool $abs Get the absolute of the difference
2589 *
2590 * @return int
2591 */
2592 public function diffInMonths(Carbon $dt = null, $abs = true)
2593 {
2594 $dt = $dt ?: static::now($this->getTimezone());
2595
2596 return $this->diffInYears($dt, $abs) * static::MONTHS_PER_YEAR + (int) $this->diff($dt, $abs)->format('%r%m');
2597 }
2598
2599 /**
2600 * Get the difference in weeks
2601 *
2602 * @param \Carbon\Carbon|null $dt
2603 * @param bool $abs Get the absolute of the difference
2604 *
2605 * @return int
2606 */
2607 public function diffInWeeks(Carbon $dt = null, $abs = true)
2608 {
2609 return (int) ($this->diffInDays($dt, $abs) / static::DAYS_PER_WEEK);
2610 }
2611
2612 /**
2613 * Get the difference in days
2614 *
2615 * @param \Carbon\Carbon|null $dt
2616 * @param bool $abs Get the absolute of the difference
2617 *
2618 * @return int
2619 */
2620 public function diffInDays(Carbon $dt = null, $abs = true)
2621 {
2622 $dt = $dt ?: static::now($this->getTimezone());
2623
2624 return (int) $this->diff($dt, $abs)->format('%r%a');
2625 }
2626
2627 /**
2628 * Get the difference in days using a filter closure
2629 *
2630 * @param Closure $callback
2631 * @param \Carbon\Carbon|null $dt
2632 * @param bool $abs Get the absolute of the difference
2633 *
2634 * @return int
2635 */
2636 public function diffInDaysFiltered(Closure $callback, Carbon $dt = null, $abs = true)
2637 {
2638 return $this->diffFiltered(CarbonInterval::day(), $callback, $dt, $abs);
2639 }
2640
2641 /**
2642 * Get the difference in hours using a filter closure
2643 *
2644 * @param Closure $callback
2645 * @param \Carbon\Carbon|null $dt
2646 * @param bool $abs Get the absolute of the difference
2647 *
2648 * @return int
2649 */
2650 public function diffInHoursFiltered(Closure $callback, Carbon $dt = null, $abs = true)
2651 {
2652 return $this->diffFiltered(CarbonInterval::hour(), $callback, $dt, $abs);
2653 }
2654
2655 /**
2656 * Get the difference by the given interval using a filter closure
2657 *
2658 * @param CarbonInterval $ci An interval to traverse by
2659 * @param Closure $callback
2660 * @param Carbon|null $dt
2661 * @param bool $abs Get the absolute of the difference
2662 *
2663 * @return int
2664 */
2665 public function diffFiltered(CarbonInterval $ci, Closure $callback, Carbon $dt = null, $abs = true)
2666 {
2667 $start = $this;
2668 $end = $dt ?: static::now($this->getTimezone());
2669 $inverse = false;
2670
2671 if ($end < $start) {
2672 $start = $end;
2673 $end = $this;
2674 $inverse = true;
2675 }
2676
2677 $period = new DatePeriod($start, $ci, $end);
2678 $vals = array_filter(iterator_to_array($period), function (DateTime $date) use ($callback) {
2679 return call_user_func($callback, Carbon::instance($date));
2680 });
2681
2682 $diff = count($vals);
2683
2684 return $inverse && !$abs ? -$diff : $diff;
2685 }
2686
2687 /**
2688 * Get the difference in weekdays
2689 *
2690 * @param \Carbon\Carbon|null $dt
2691 * @param bool $abs Get the absolute of the difference
2692 *
2693 * @return int
2694 */
2695 public function diffInWeekdays(Carbon $dt = null, $abs = true)
2696 {
2697 return $this->diffInDaysFiltered(function (Carbon $date) {
2698 return $date->isWeekday();
2699 }, $dt, $abs);
2700 }
2701
2702 /**
2703 * Get the difference in weekend days using a filter
2704 *
2705 * @param \Carbon\Carbon|null $dt
2706 * @param bool $abs Get the absolute of the difference
2707 *
2708 * @return int
2709 */
2710 public function diffInWeekendDays(Carbon $dt = null, $abs = true)
2711 {
2712 return $this->diffInDaysFiltered(function (Carbon $date) {
2713 return $date->isWeekend();
2714 }, $dt, $abs);
2715 }
2716
2717 /**
2718 * Get the difference in hours
2719 *
2720 * @param \Carbon\Carbon|null $dt
2721 * @param bool $abs Get the absolute of the difference
2722 *
2723 * @return int
2724 */
2725 public function diffInHours(Carbon $dt = null, $abs = true)
2726 {
2727 return (int) ($this->diffInSeconds($dt, $abs) / static::SECONDS_PER_MINUTE / static::MINUTES_PER_HOUR);
2728 }
2729
2730 /**
2731 * Get the difference in minutes
2732 *
2733 * @param \Carbon\Carbon|null $dt
2734 * @param bool $abs Get the absolute of the difference
2735 *
2736 * @return int
2737 */
2738 public function diffInMinutes(Carbon $dt = null, $abs = true)
2739 {
2740 return (int) ($this->diffInSeconds($dt, $abs) / static::SECONDS_PER_MINUTE);
2741 }
2742
2743 /**
2744 * Get the difference in seconds
2745 *
2746 * @param \Carbon\Carbon|null $dt
2747 * @param bool $abs Get the absolute of the difference
2748 *
2749 * @return int
2750 */
2751 public function diffInSeconds(Carbon $dt = null, $abs = true)
2752 {
2753 $dt = $dt ?: static::now($this->getTimezone());
2754 $value = $dt->getTimestamp() - $this->getTimestamp();
2755
2756 return $abs ? abs($value) : $value;
2757 }
2758
2759 /**
2760 * The number of seconds since midnight.
2761 *
2762 * @return int
2763 */
2764 public function secondsSinceMidnight()
2765 {
2766 return $this->diffInSeconds($this->copy()->startOfDay());
2767 }
2768
2769 /**
2770 * The number of seconds until 23:23:59.
2771 *
2772 * @return int
2773 */
2774 public function secondsUntilEndOfDay()
2775 {
2776 return $this->diffInSeconds($this->copy()->endOfDay());
2777 }
2778
2779 /**
2780 * Get the difference in a human readable format in the current locale.
2781 *
2782 * When comparing a value in the past to default now:
2783 * 1 hour ago
2784 * 5 months ago
2785 *
2786 * When comparing a value in the future to default now:
2787 * 1 hour from now
2788 * 5 months from now
2789 *
2790 * When comparing a value in the past to another value:
2791 * 1 hour before
2792 * 5 months before
2793 *
2794 * When comparing a value in the future to another value:
2795 * 1 hour after
2796 * 5 months after
2797 *
2798 * @param Carbon|null $other
2799 * @param bool $absolute removes time difference modifiers ago, after, etc
2800 * @param bool $short displays short format of time units
2801 *
2802 * @return string
2803 */
2804 public function diffForHumans(Carbon $other = null, $absolute = false, $short = false)
2805 {
2806 $isNow = $other === null;
2807
2808 if ($isNow) {
2809 $other = static::now($this->getTimezone());
2810 }
2811
2812 $diffInterval = $this->diff($other);
2813
2814 switch (true) {
2815 case $diffInterval->y > 0:
2816 $unit = $short ? 'y' : 'year';
2817 $count = $diffInterval->y;
2818 break;
2819
2820 case $diffInterval->m > 0:
2821 $unit = $short ? 'm' : 'month';
2822 $count = $diffInterval->m;
2823 break;
2824
2825 case $diffInterval->d > 0:
2826 $unit = $short ? 'd' : 'day';
2827 $count = $diffInterval->d;
2828
2829 if ($count >= static::DAYS_PER_WEEK) {
2830 $unit = $short ? 'w' : 'week';
2831 $count = (int) ($count / static::DAYS_PER_WEEK);
2832 }
2833 break;
2834
2835 case $diffInterval->h > 0:
2836 $unit = $short ? 'h' : 'hour';
2837 $count = $diffInterval->h;
2838 break;
2839
2840 case $diffInterval->i > 0:
2841 $unit = $short ? 'min' : 'minute';
2842 $count = $diffInterval->i;
2843 break;
2844
2845 default:
2846 $count = $diffInterval->s;
2847 $unit = $short ? 's' : 'second';
2848 break;
2849 }
2850
2851 if ($count === 0) {
2852 $count = 1;
2853 }
2854
2855 $time = static::translator()->transChoice($unit, $count, array(':count' => $count));
2856
2857 if ($absolute) {
2858 return $time;
2859 }
2860
2861 $isFuture = $diffInterval->invert === 1;
2862
2863 $transId = $isNow ? ($isFuture ? 'from_now' : 'ago') : ($isFuture ? 'after' : 'before');
2864
2865 // Some langs have special pluralization for past and future tense.
2866 $tryKeyExists = $unit.'_'.$transId;
2867 if ($tryKeyExists !== static::translator()->transChoice($tryKeyExists, $count)) {
2868 $time = static::translator()->transChoice($tryKeyExists, $count, array(':count' => $count));
2869 }
2870
2871 return static::translator()->trans($transId, array(':time' => $time));
2872 }
2873
2874 ///////////////////////////////////////////////////////////////////
2875 //////////////////////////// MODIFIERS ////////////////////////////
2876 ///////////////////////////////////////////////////////////////////
2877
2878 /**
2879 * Resets the time to 00:00:00
2880 *
2881 * @return static
2882 */
2883 public function startOfDay()
2884 {
2885 return $this->setTime(0, 0, 0);
2886 }
2887
2888 /**
2889 * Resets the time to 23:59:59
2890 *
2891 * @return static
2892 */
2893 public function endOfDay()
2894 {
2895 return $this->setTime(23, 59, 59);
2896 }
2897
2898 /**
2899 * Resets the date to the first day of the month and the time to 00:00:00
2900 *
2901 * @return static
2902 */
2903 public function startOfMonth()
2904 {
2905 return $this->setDateTime($this->year, $this->month, 1, 0, 0, 0);
2906 }
2907
2908 /**
2909 * Resets the date to end of the month and time to 23:59:59
2910 *
2911 * @return static
2912 */
2913 public function endOfMonth()
2914 {
2915 return $this->setDateTime($this->year, $this->month, $this->daysInMonth, 23, 59, 59);
2916 }
2917
2918 /**
2919 * Resets the date to the first day of the quarter and the time to 00:00:00
2920 *
2921 * @return static
2922 */
2923 public function startOfQuarter()
2924 {
2925 $month = ($this->quarter - 1) * static::MONTHS_PER_QUARTER + 1;
2926
2927 return $this->setDateTime($this->year, $month, 1, 0, 0, 0);
2928 }
2929
2930 /**
2931 * Resets the date to end of the quarter and time to 23:59:59
2932 *
2933 * @return static
2934 */
2935 public function endOfQuarter()
2936 {
2937 return $this->startOfQuarter()->addMonths(static::MONTHS_PER_QUARTER - 1)->endOfMonth();
2938 }
2939
2940 /**
2941 * Resets the date to the first day of the year and the time to 00:00:00
2942 *
2943 * @return static
2944 */
2945 public function startOfYear()
2946 {
2947 return $this->setDateTime($this->year, 1, 1, 0, 0, 0);
2948 }
2949
2950 /**
2951 * Resets the date to end of the year and time to 23:59:59
2952 *
2953 * @return static
2954 */
2955 public function endOfYear()
2956 {
2957 return $this->setDateTime($this->year, 12, 31, 23, 59, 59);
2958 }
2959
2960 /**
2961 * Resets the date to the first day of the decade and the time to 00:00:00
2962 *
2963 * @return static
2964 */
2965 public function startOfDecade()
2966 {
2967 $year = $this->year - $this->year % static::YEARS_PER_DECADE;
2968
2969 return $this->setDateTime($year, 1, 1, 0, 0, 0);
2970 }
2971
2972 /**
2973 * Resets the date to end of the decade and time to 23:59:59
2974 *
2975 * @return static
2976 */
2977 public function endOfDecade()
2978 {
2979 $year = $this->year - $this->year % static::YEARS_PER_DECADE + static::YEARS_PER_DECADE - 1;
2980
2981 return $this->setDateTime($year, 12, 31, 23, 59, 59);
2982 }
2983
2984 /**
2985 * Resets the date to the first day of the century and the time to 00:00:00
2986 *
2987 * @return static
2988 */
2989 public function startOfCentury()
2990 {
2991 $year = $this->year - ($this->year - 1) % static::YEARS_PER_CENTURY;
2992
2993 return $this->setDateTime($year, 1, 1, 0, 0, 0);
2994 }
2995
2996 /**
2997 * Resets the date to end of the century and time to 23:59:59
2998 *
2999 * @return static
3000 */
3001 public function endOfCentury()
3002 {
3003 $year = $this->year - 1 - ($this->year - 1) % static::YEARS_PER_CENTURY + static::YEARS_PER_CENTURY;
3004
3005 return $this->setDateTime($year, 12, 31, 23, 59, 59);
3006 }
3007
3008 /**
3009 * Resets the date to the first day of week (defined in $weekStartsAt) and the time to 00:00:00
3010 *
3011 * @return static
3012 */
3013 public function startOfWeek()
3014 {
3015 while ($this->dayOfWeek !== static::$weekStartsAt) {
3016 $this->subDay();
3017 }
3018
3019 return $this->startOfDay();
3020 }
3021
3022 /**
3023 * Resets the date to end of week (defined in $weekEndsAt) and time to 23:59:59
3024 *
3025 * @return static
3026 */
3027 public function endOfWeek()
3028 {
3029 while ($this->dayOfWeek !== static::$weekEndsAt) {
3030 $this->addDay();
3031 }
3032
3033 return $this->endOfDay();
3034 }
3035
3036 /**
3037 * Modify to the next occurrence of a given day of the week.
3038 * If no dayOfWeek is provided, modify to the next occurrence
3039 * of the current day of the week. Use the supplied constants
3040 * to indicate the desired dayOfWeek, ex. static::MONDAY.
3041 *
3042 * @param int|null $dayOfWeek
3043 *
3044 * @return static
3045 */
3046 public function next($dayOfWeek = null)
3047 {
3048 if ($dayOfWeek === null) {
3049 $dayOfWeek = $this->dayOfWeek;
3050 }
3051
3052 return $this->startOfDay()->modify('next '.static::$days[$dayOfWeek]);
3053 }
3054
3055 /**
3056 * Go forward or backward to the next week- or weekend-day.
3057 *
3058 * @param bool $weekday
3059 * @param bool $forward
3060 *
3061 * @return $this
3062 */
3063 private function nextOrPreviousDay($weekday = true, $forward = true)
3064 {
3065 $step = $forward ? 1 : -1;
3066
3067 do {
3068 $this->addDay($step);
3069 } while ($weekday ? $this->isWeekend() : $this->isWeekday());
3070
3071 return $this;
3072 }
3073
3074 /**
3075 * Go forward to the next weekday.
3076 *
3077 * @return $this
3078 */
3079 public function nextWeekday()
3080 {
3081 return $this->nextOrPreviousDay();
3082 }
3083
3084 /**
3085 * Go backward to the previous weekday.
3086 *
3087 * @return $this
3088 */
3089 public function previousWeekday()
3090 {
3091 return $this->nextOrPreviousDay(true, false);
3092 }
3093
3094 /**
3095 * Go forward to the next weekend day.
3096 *
3097 * @return $this
3098 */
3099 public function nextWeekendDay()
3100 {
3101 return $this->nextOrPreviousDay(false);
3102 }
3103
3104 /**
3105 * Go backward to the previous weekend day.
3106 *
3107 * @return $this
3108 */
3109 public function previousWeekendDay()
3110 {
3111 return $this->nextOrPreviousDay(false, false);
3112 }
3113
3114 /**
3115 * Modify to the previous occurrence of a given day of the week.
3116 * If no dayOfWeek is provided, modify to the previous occurrence
3117 * of the current day of the week. Use the supplied constants
3118 * to indicate the desired dayOfWeek, ex. static::MONDAY.
3119 *
3120 * @param int|null $dayOfWeek
3121 *
3122 * @return static
3123 */
3124 public function previous($dayOfWeek = null)
3125 {
3126 if ($dayOfWeek === null) {
3127 $dayOfWeek = $this->dayOfWeek;
3128 }
3129
3130 return $this->startOfDay()->modify('last '.static::$days[$dayOfWeek]);
3131 }
3132
3133 /**
3134 * Modify to the first occurrence of a given day of the week
3135 * in the current month. If no dayOfWeek is provided, modify to the
3136 * first day of the current month. Use the supplied constants
3137 * to indicate the desired dayOfWeek, ex. static::MONDAY.
3138 *
3139 * @param int|null $dayOfWeek
3140 *
3141 * @return static
3142 */
3143 public function firstOfMonth($dayOfWeek = null)
3144 {
3145 $this->startOfDay();
3146
3147 if ($dayOfWeek === null) {
3148 return $this->day(1);
3149 }
3150
3151 return $this->modify('first '.static::$days[$dayOfWeek].' of '.$this->format('F').' '.$this->year);
3152 }
3153
3154 /**
3155 * Modify to the last occurrence of a given day of the week
3156 * in the current month. If no dayOfWeek is provided, modify to the
3157 * last day of the current month. Use the supplied constants
3158 * to indicate the desired dayOfWeek, ex. static::MONDAY.
3159 *
3160 * @param int|null $dayOfWeek
3161 *
3162 * @return static
3163 */
3164 public function lastOfMonth($dayOfWeek = null)
3165 {
3166 $this->startOfDay();
3167
3168 if ($dayOfWeek === null) {
3169 return $this->day($this->daysInMonth);
3170 }
3171
3172 return $this->modify('last '.static::$days[$dayOfWeek].' of '.$this->format('F').' '.$this->year);
3173 }
3174
3175 /**
3176 * Modify to the given occurrence of a given day of the week
3177 * in the current month. If the calculated occurrence is outside the scope
3178 * of the current month, then return false and no modifications are made.
3179 * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
3180 *
3181 * @param int $nth
3182 * @param int $dayOfWeek
3183 *
3184 * @return mixed
3185 */
3186 public function nthOfMonth($nth, $dayOfWeek)
3187 {
3188 $dt = $this->copy()->firstOfMonth();
3189 $check = $dt->format('Y-m');
3190 $dt->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
3191
3192 return $dt->format('Y-m') === $check ? $this->modify($dt) : false;
3193 }
3194
3195 /**
3196 * Modify to the first occurrence of a given day of the week
3197 * in the current quarter. If no dayOfWeek is provided, modify to the
3198 * first day of the current quarter. Use the supplied constants
3199 * to indicate the desired dayOfWeek, ex. static::MONDAY.
3200 *
3201 * @param int|null $dayOfWeek
3202 *
3203 * @return static
3204 */
3205 public function firstOfQuarter($dayOfWeek = null)
3206 {
3207 return $this->setDate($this->year, $this->quarter * static::MONTHS_PER_QUARTER - 2, 1)->firstOfMonth($dayOfWeek);
3208 }
3209
3210 /**
3211 * Modify to the last occurrence of a given day of the week
3212 * in the current quarter. If no dayOfWeek is provided, modify to the
3213 * last day of the current quarter. Use the supplied constants
3214 * to indicate the desired dayOfWeek, ex. static::MONDAY.
3215 *
3216 * @param int|null $dayOfWeek
3217 *
3218 * @return static
3219 */
3220 public function lastOfQuarter($dayOfWeek = null)
3221 {
3222 return $this->setDate($this->year, $this->quarter * static::MONTHS_PER_QUARTER, 1)->lastOfMonth($dayOfWeek);
3223 }
3224
3225 /**
3226 * Modify to the given occurrence of a given day of the week
3227 * in the current quarter. If the calculated occurrence is outside the scope
3228 * of the current quarter, then return false and no modifications are made.
3229 * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
3230 *
3231 * @param int $nth
3232 * @param int $dayOfWeek
3233 *
3234 * @return mixed
3235 */
3236 public function nthOfQuarter($nth, $dayOfWeek)
3237 {
3238 $dt = $this->copy()->day(1)->month($this->quarter * static::MONTHS_PER_QUARTER);
3239 $lastMonth = $dt->month;
3240 $year = $dt->year;
3241 $dt->firstOfQuarter()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
3242
3243 return ($lastMonth < $dt->month || $year !== $dt->year) ? false : $this->modify($dt);
3244 }
3245
3246 /**
3247 * Modify to the first occurrence of a given day of the week
3248 * in the current year. If no dayOfWeek is provided, modify to the
3249 * first day of the current year. Use the supplied constants
3250 * to indicate the desired dayOfWeek, ex. static::MONDAY.
3251 *
3252 * @param int|null $dayOfWeek
3253 *
3254 * @return static
3255 */
3256 public function firstOfYear($dayOfWeek = null)
3257 {
3258 return $this->month(1)->firstOfMonth($dayOfWeek);
3259 }
3260
3261 /**
3262 * Modify to the last occurrence of a given day of the week
3263 * in the current year. If no dayOfWeek is provided, modify to the
3264 * last day of the current year. Use the supplied constants
3265 * to indicate the desired dayOfWeek, ex. static::MONDAY.
3266 *
3267 * @param int|null $dayOfWeek
3268 *
3269 * @return static
3270 */
3271 public function lastOfYear($dayOfWeek = null)
3272 {
3273 return $this->month(static::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek);
3274 }
3275
3276 /**
3277 * Modify to the given occurrence of a given day of the week
3278 * in the current year. If the calculated occurrence is outside the scope
3279 * of the current year, then return false and no modifications are made.
3280 * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
3281 *
3282 * @param int $nth
3283 * @param int $dayOfWeek
3284 *
3285 * @return mixed
3286 */
3287 public function nthOfYear($nth, $dayOfWeek)
3288 {
3289 $dt = $this->copy()->firstOfYear()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
3290
3291 return $this->year === $dt->year ? $this->modify($dt) : false;
3292 }
3293
3294 /**
3295 * Modify the current instance to the average of a given instance (default now) and the current instance.
3296 *
3297 * @param \Carbon\Carbon|null $dt
3298 *
3299 * @return static
3300 */
3301 public function average(Carbon $dt = null)
3302 {
3303 $dt = $dt ?: static::now($this->getTimezone());
3304
3305 return $this->addSeconds((int) ($this->diffInSeconds($dt, false) / 2));
3306 }
3307
3308 /**
3309 * Check if its the birthday. Compares the date/month values of the two dates.
3310 *
3311 * @param \Carbon\Carbon|null $dt The instance to compare with or null to use current day.
3312 *
3313 * @return bool
3314 */
3315 public function isBirthday(Carbon $dt = null)
3316 {
3317 return $this->isSameAs('md', $dt);
3318 }
3319
3320 /**
3321 * Consider the timezone when modifying the instance.
3322 *
3323 * @param string $modify
3324 *
3325 * @return static
3326 */
3327 public function modify($modify)
3328 {
3329 if ($this->local) {
3330 return parent::modify($modify);
3331 }
3332
3333 $timezone = $this->getTimezone();
3334 $this->setTimezone('UTC');
3335 $instance = parent::modify($modify);
3336 $this->setTimezone($timezone);
3337
3338 return $instance;
3339 }
3340
3341 /**
3342 * Return a serialized string of the instance.
3343 *
3344 * @return string
3345 */
3346 public function serialize()
3347 {
3348 return serialize($this);
3349 }
3350
3351 /**
3352 * Create an instance form a serialized string.
3353 *
3354 * @param string $value
3355 *
3356 * @throws \InvalidArgumentException
3357 *
3358 * @return static
3359 */
3360 public static function fromSerialized($value)
3361 {
3362 $instance = @unserialize($value);
3363
3364 if (!$instance instanceof static) {
3365 throw new InvalidArgumentException('Invalid serialized value.');
3366 }
3367
3368 return $instance;
3369 }
3370 }
3371