PluginProbe
Stream – Activity Log & Audit Trail / 3.0.7
Stream – Activity Log & Audit Trail v3.0.7
4.4.0 4.3.0 4.2.2 4.2.1 trunk 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.1 3.1.1 3.10.0 3.2.0 3.2.1 3.2.2 3.2.3 All 50 releases
stream / includes / lib / Carbon.php

Carbon.php in Stream – Activity Log & Audit Trail 3.0.7, at includes/lib/Carbon.php

2,213 lines 53.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 Closure;
15 use DateTime;
16 use DateTimeZone;
17 use DateInterval;
18 use DatePeriod;
19 use InvalidArgumentException;
20
21 /**
22 * A simple API extension for DateTime
23 *
24 * @property integer $year
25 * @property integer $month
26 * @property integer $day
27 * @property integer $hour
28 * @property integer $minute
29 * @property integer $second
30 * @property integer $timestamp seconds since the Unix Epoch
31 * @property-read integer $micro
32 * @property-read integer $dayOfWeek 0 (for Sunday) through 6 (for Saturday)
33 * @property-read integer $dayOfYear 0 through 365
34 * @property-read integer $weekOfMonth 1 through 6
35 * @property-read integer $weekOfYear ISO-8601 week number of year, weeks starting on Monday
36 * @property-read integer $daysInMonth number of days in the given month
37 * @property-read integer $age does a diffInYears() with default parameters
38 * @property-read integer $quarter the quarter of this instance, 1 - 4
39 * @property-read integer $offset the timezone offset in seconds from UTC
40 * @property-read integer $offsetHours the timezone offset in hours from UTC
41 * @property-read boolean $dst daylight savings time indicator, true if DST, false otherwise
42 * @property-read boolean $local checks if the timezone is local, true if local, false otherwise
43 * @property-read boolean $utc checks if the timezone is UTC, true if UTC, false otherwise
44 * @property-read string $timezoneName
45 * @property-read string $tzName
46 *
47 * @property-read DateTimeZone $timezone the current timezone
48 * @property-read DateTimeZone $tz alias of timezone
49 * @property-write DateTimeZone|string $timezone the current timezone
50 * @property-write DateTimeZone|string $tz alias of timezone
51 *
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 for testing purposes
83 *
84 * @var array
85 */
86 protected static $relativeKeywords = array(
87 'this',
88 'next',
89 'last',
90 'tomorrow',
91 'yesterday',
92 '+',
93 '-',
94 'first',
95 'last',
96 'ago'
97 );
98
99 /**
100 * Number of X in Y
101 */
102 const YEARS_PER_CENTURY = 100;
103 const YEARS_PER_DECADE = 10;
104 const MONTHS_PER_YEAR = 12;
105 const WEEKS_PER_YEAR = 52;
106 const DAYS_PER_WEEK = 7;
107 const HOURS_PER_DAY = 24;
108 const MINUTES_PER_HOUR = 60;
109 const SECONDS_PER_MINUTE = 60;
110
111 /**
112 * Default format to use for __toString method when type juggling occurs.
113 *
114 * @var string
115 */
116 const DEFAULT_TO_STRING_FORMAT = 'Y-m-d H:i:s';
117
118 /**
119 * Format to use for __toString method when type juggling occurs.
120 *
121 * @var string
122 */
123 protected static $toStringFormat = self::DEFAULT_TO_STRING_FORMAT;
124
125 /**
126 * A test Carbon instance to be returned when now instances are created
127 *
128 * @var Carbon
129 */
130 protected static $testNow;
131
132 /**
133 * Creates a DateTimeZone from a string or a DateTimeZone
134 *
135 * @param DateTimeZone|string $object
136 *
137 * @return DateTimeZone
138 *
139 * @throws InvalidArgumentException
140 */
141 protected static function safeCreateDateTimeZone($object)
142 {
143 if ($object instanceof DateTimeZone) {
144 return $object;
145 }
146
147 $tz = @timezone_open((string) $object);
148
149 if ($tz === false) {
150 throw new InvalidArgumentException('Unknown or bad timezone ('.$object.')');
151 }
152
153 return $tz;
154 }
155
156 ///////////////////////////////////////////////////////////////////
157 //////////////////////////// CONSTRUCTORS /////////////////////////
158 ///////////////////////////////////////////////////////////////////
159
160 /**
161 * Create a new Carbon instance.
162 *
163 * Please see the testing aids section (specifically static::setTestNow())
164 * for more on the possibility of this constructor returning a test instance.
165 *
166 * @param string $time
167 * @param DateTimeZone|string $tz
168 */
169 public function __construct($time = null, $tz = null)
170 {
171 // If the class has a test now set and we are trying to create a now()
172 // instance then override as required
173 if (static::hasTestNow() && (empty($time) || $time === 'now' || static::hasRelativeKeywords($time))) {
174 $testInstance = clone static::getTestNow();
175 if (static::hasRelativeKeywords($time)) {
176 $testInstance->modify($time);
177 }
178
179 //shift the time according to the given time zone
180 if ($tz !== NULL && $tz != static::getTestNow()->tz) {
181 $testInstance->setTimezone($tz);
182 } else {
183 $tz = $testInstance->tz;
184 }
185
186 $time = $testInstance->toDateTimeString();
187 }
188
189 if ($tz !== null) {
190 parent::__construct($time, static::safeCreateDateTimeZone($tz));
191 } else {
192 parent::__construct($time);
193 }
194 }
195
196 /**
197 * Create a Carbon instance from a DateTime one
198 *
199 * @param DateTime $dt
200 *
201 * @return static
202 */
203 public static function instance(DateTime $dt)
204 {
205 return new static($dt->format('Y-m-d H:i:s.u'), $dt->getTimeZone());
206 }
207
208 /**
209 * Create a carbon instance from a string. This is an alias for the
210 * constructor that allows better fluent syntax as it allows you to do
211 * Carbon::parse('Monday next week')->fn() rather than
212 * (new Carbon('Monday next week'))->fn()
213 *
214 * @param string $time
215 * @param DateTimeZone|string $tz
216 *
217 * @return static
218 */
219 public static function parse($time = null, $tz = null)
220 {
221 return new static($time, $tz);
222 }
223
224 /**
225 * Get a Carbon instance for the current date and time
226 *
227 * @param DateTimeZone|string $tz
228 *
229 * @return static
230 */
231 public static function now($tz = null)
232 {
233 return new static(null, $tz);
234 }
235
236 /**
237 * Create a Carbon instance for today
238 *
239 * @param DateTimeZone|string $tz
240 *
241 * @return static
242 */
243 public static function today($tz = null)
244 {
245 return static::now($tz)->startOfDay();
246 }
247
248 /**
249 * Create a Carbon instance for tomorrow
250 *
251 * @param DateTimeZone|string $tz
252 *
253 * @return static
254 */
255 public static function tomorrow($tz = null)
256 {
257 return static::today($tz)->addDay();
258 }
259
260 /**
261 * Create a Carbon instance for yesterday
262 *
263 * @param DateTimeZone|string $tz
264 *
265 * @return static
266 */
267 public static function yesterday($tz = null)
268 {
269 return static::today($tz)->subDay();
270 }
271
272 /**
273 * Create a Carbon instance for the greatest supported date.
274 *
275 * @return Carbon
276 */
277 public static function maxValue()
278 {
279 return static::createFromTimestamp(PHP_INT_MAX);
280 }
281
282 /**
283 * Create a Carbon instance for the lowest supported date.
284 *
285 * @return Carbon
286 */
287 public static function minValue()
288 {
289 return static::createFromTimestamp(~PHP_INT_MAX);
290 }
291
292 /**
293 * Create a new Carbon instance from a specific date and time.
294 *
295 * If any of $year, $month or $day are set to null their now() values
296 * will be used.
297 *
298 * If $hour is null it will be set to its now() value and the default values
299 * for $minute and $second will be their now() values.
300 * If $hour is not null then the default values for $minute and $second
301 * will be 0.
302 *
303 * @param integer $year
304 * @param integer $month
305 * @param integer $day
306 * @param integer $hour
307 * @param integer $minute
308 * @param integer $second
309 * @param DateTimeZone|string $tz
310 *
311 * @return static
312 */
313 public static function create($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
314 {
315 $year = ($year === null) ? date('Y') : $year;
316 $month = ($month === null) ? date('n') : $month;
317 $day = ($day === null) ? date('j') : $day;
318
319 if ($hour === null) {
320 $hour = date('G');
321 $minute = ($minute === null) ? date('i') : $minute;
322 $second = ($second === null) ? date('s') : $second;
323 } else {
324 $minute = ($minute === null) ? 0 : $minute;
325 $second = ($second === null) ? 0 : $second;
326 }
327
328 return static::createFromFormat('Y-n-j G:i:s', sprintf('%s-%s-%s %s:%02s:%02s', $year, $month, $day, $hour, $minute, $second), $tz);
329 }
330
331 /**
332 * Create a Carbon instance from just a date. The time portion is set to now.
333 *
334 * @param integer $year
335 * @param integer $month
336 * @param integer $day
337 * @param DateTimeZone|string $tz
338 *
339 * @return static
340 */
341 public static function createFromDate($year = null, $month = null, $day = null, $tz = null)
342 {
343 return static::create($year, $month, $day, null, null, null, $tz);
344 }
345
346 /**
347 * Create a Carbon instance from just a time. The date portion is set to today.
348 *
349 * @param integer $hour
350 * @param integer $minute
351 * @param integer $second
352 * @param DateTimeZone|string $tz
353 *
354 * @return static
355 */
356 public static function createFromTime($hour = null, $minute = null, $second = null, $tz = null)
357 {
358 return static::create(null, null, null, $hour, $minute, $second, $tz);
359 }
360
361 /**
362 * Create a Carbon instance from a specific format
363 *
364 * @param string $format
365 * @param string $time
366 * @param DateTimeZone|string $tz
367 *
368 * @return static
369 *
370 * @throws InvalidArgumentException
371 */
372 public static function createFromFormat($format, $time, $tz = null)
373 {
374 if ($tz !== null) {
375 $dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz));
376 } else {
377 $dt = parent::createFromFormat($format, $time);
378 }
379
380 if ($dt instanceof DateTime) {
381 return static::instance($dt);
382 }
383
384 $errors = static::getLastErrors();
385 throw new InvalidArgumentException(implode(PHP_EOL, $errors['errors']));
386 }
387
388 /**
389 * Create a Carbon instance from a timestamp
390 *
391 * @param integer $timestamp
392 * @param DateTimeZone|string $tz
393 *
394 * @return static
395 */
396 public static function createFromTimestamp($timestamp, $tz = null)
397 {
398 return static::now($tz)->setTimestamp($timestamp);
399 }
400
401 /**
402 * Create a Carbon instance from an UTC timestamp
403 *
404 * @param integer $timestamp
405 *
406 * @return static
407 */
408 public static function createFromTimestampUTC($timestamp)
409 {
410 return new static('@'.$timestamp);
411 }
412
413 /**
414 * Get a copy of the instance
415 *
416 * @return static
417 */
418 public function copy()
419 {
420 return static::instance($this);
421 }
422
423 ///////////////////////////////////////////////////////////////////
424 ///////////////////////// GETTERS AND SETTERS /////////////////////
425 ///////////////////////////////////////////////////////////////////
426
427 /**
428 * Get a part of the Carbon object
429 *
430 * @param string $name
431 *
432 * @throws InvalidArgumentException
433 *
434 * @return string|integer|DateTimeZone
435 */
436 public function __get($name)
437 {
438 switch ($name) {
439 case 'year':
440 case 'month':
441 case 'day':
442 case 'hour':
443 case 'minute':
444 case 'second':
445 case 'micro':
446 case 'dayOfWeek':
447 case 'dayOfYear':
448 case 'weekOfYear':
449 case 'daysInMonth':
450 case 'timestamp':
451 $formats = array(
452 'year' => 'Y',
453 'month' => 'n',
454 'day' => 'j',
455 'hour' => 'G',
456 'minute' => 'i',
457 'second' => 's',
458 'micro' => 'u',
459 'dayOfWeek' => 'w',
460 'dayOfYear' => 'z',
461 'weekOfYear' => 'W',
462 'daysInMonth' => 't',
463 'timestamp' => 'U',
464 );
465
466 return (int) $this->format($formats[$name]);
467
468 case 'weekOfMonth':
469 return (int) ceil($this->day / self::DAYS_PER_WEEK);
470
471 case 'age':
472 return (int) $this->diffInYears();
473
474 case 'quarter':
475 return (int) ceil($this->month / 3);
476
477 case 'offset':
478 return $this->getOffset();
479
480 case 'offsetHours':
481 return $this->getOffset() / self::SECONDS_PER_MINUTE / self::MINUTES_PER_HOUR;
482
483 case 'dst':
484 return $this->format('I') == '1';
485
486 case 'local':
487 return $this->offset == $this->copy()->setTimezone(date_default_timezone_get())->offset;
488
489 case 'utc':
490 return $this->offset == 0;
491
492 case 'timezone':
493 case 'tz':
494 return $this->getTimezone();
495
496 case 'timezoneName':
497 case 'tzName':
498 return $this->getTimezone()->getName();
499
500 default:
501 throw new InvalidArgumentException(sprintf("Unknown getter '%s'", $name));
502 }
503 }
504
505 /**
506 * Check if an attribute exists on the object
507 *
508 * @param string $name
509 *
510 * @return boolean
511 */
512 public function __isset($name)
513 {
514 try {
515 $this->__get($name);
516 } catch (InvalidArgumentException $e) {
517 return false;
518 }
519
520 return true;
521 }
522
523 /**
524 * Set a part of the Carbon object
525 *
526 * @param string $name
527 * @param string|integer|DateTimeZone $value
528 *
529 * @throws InvalidArgumentException
530 */
531 public function __set($name, $value)
532 {
533 switch ($name) {
534 case 'year':
535 parent::setDate($value, $this->month, $this->day);
536 break;
537
538 case 'month':
539 parent::setDate($this->year, $value, $this->day);
540 break;
541
542 case 'day':
543 parent::setDate($this->year, $this->month, $value);
544 break;
545
546 case 'hour':
547 parent::setTime($value, $this->minute, $this->second);
548 break;
549
550 case 'minute':
551 parent::setTime($this->hour, $value, $this->second);
552 break;
553
554 case 'second':
555 parent::setTime($this->hour, $this->minute, $value);
556 break;
557
558 case 'timestamp':
559 parent::setTimestamp($value);
560 break;
561
562 case 'timezone':
563 case 'tz':
564 $this->setTimezone($value);
565 break;
566
567 default:
568 throw new InvalidArgumentException(sprintf("Unknown setter '%s'", $name));
569 }
570 }
571
572 /**
573 * Set the instance's year
574 *
575 * @param integer $value
576 *
577 * @return static
578 */
579 public function year($value)
580 {
581 $this->year = $value;
582
583 return $this;
584 }
585
586 /**
587 * Set the instance's month
588 *
589 * @param integer $value
590 *
591 * @return static
592 */
593 public function month($value)
594 {
595 $this->month = $value;
596
597 return $this;
598 }
599
600 /**
601 * Set the instance's day
602 *
603 * @param integer $value
604 *
605 * @return static
606 */
607 public function day($value)
608 {
609 $this->day = $value;
610
611 return $this;
612 }
613
614 /**
615 * Set the date all together
616 *
617 * @param integer $year
618 * @param integer $month
619 * @param integer $day
620 *
621 * @return static
622 */
623 public function setDate($year, $month, $day)
624 {
625 parent::setDate($year, $month, $day);
626
627 return $this;
628 }
629
630 /**
631 * Set the instance's hour
632 *
633 * @param integer $value
634 *
635 * @return static
636 */
637 public function hour($value)
638 {
639 $this->hour = $value;
640
641 return $this;
642 }
643
644 /**
645 * Set the instance's minute
646 *
647 * @param integer $value
648 *
649 * @return static
650 */
651 public function minute($value)
652 {
653 $this->minute = $value;
654
655 return $this;
656 }
657
658 /**
659 * Set the instance's second
660 *
661 * @param integer $value
662 *
663 * @return static
664 */
665 public function second($value)
666 {
667 $this->second = $value;
668
669 return $this;
670 }
671
672 /**
673 * Set the time all together
674 *
675 * @param integer $hour
676 * @param integer $minute
677 * @param integer $second
678 *
679 * @return static
680 */
681 public function setTime($hour, $minute, $second = 0)
682 {
683 parent::setTime($hour, $minute, $second);
684
685 return $this;
686 }
687
688 /**
689 * Set the date and time all together
690 *
691 * @param integer $year
692 * @param integer $month
693 * @param integer $day
694 * @param integer $hour
695 * @param integer $minute
696 * @param integer $second
697 *
698 * @return static
699 */
700 public function setDateTime($year, $month, $day, $hour, $minute, $second = 0)
701 {
702 return $this->setDate($year, $month, $day)->setTime($hour, $minute, $second);
703 }
704
705 /**
706 * Set the instance's timestamp
707 *
708 * @param integer $value
709 *
710 * @return static
711 */
712 public function timestamp($value)
713 {
714 $this->timestamp = $value;
715
716 return $this;
717 }
718
719 /**
720 * Alias for setTimezone()
721 *
722 * @param DateTimeZone|string $value
723 *
724 * @return static
725 */
726 public function timezone($value)
727 {
728 return $this->setTimezone($value);
729 }
730
731 /**
732 * Alias for setTimezone()
733 *
734 * @param DateTimeZone|string $value
735 *
736 * @return static
737 */
738 public function tz($value)
739 {
740 return $this->setTimezone($value);
741 }
742
743 /**
744 * Set the instance's timezone from a string or object
745 *
746 * @param DateTimeZone|string $value
747 *
748 * @return static
749 */
750 public function setTimezone($value)
751 {
752 parent::setTimezone(static::safeCreateDateTimeZone($value));
753
754 return $this;
755 }
756
757 ///////////////////////////////////////////////////////////////////
758 ///////////////////////// TESTING AIDS ////////////////////////////
759 ///////////////////////////////////////////////////////////////////
760
761 /**
762 * Set a Carbon instance (real or mock) to be returned when a "now"
763 * instance is created. The provided instance will be returned
764 * specifically under the following conditions:
765 * - A call to the static now() method, ex. Carbon::now()
766 * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
767 * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
768 *
769 * Note the timezone parameter was left out of the examples above and
770 * has no affect as the mock value will be returned regardless of its value.
771 *
772 * To clear the test instance call this method using the default
773 * parameter of null.
774 *
775 * @param Carbon $testNow
776 */
777 public static function setTestNow(Carbon $testNow = null)
778 {
779 static::$testNow = $testNow;
780 }
781
782 /**
783 * Get the Carbon instance (real or mock) to be returned when a "now"
784 * instance is created.
785 *
786 * @return static the current instance used for testing
787 */
788 public static function getTestNow()
789 {
790 return static::$testNow;
791 }
792
793 /**
794 * Determine if there is a valid test instance set. A valid test instance
795 * is anything that is not null.
796 *
797 * @return boolean true if there is a test instance, otherwise false
798 */
799 public static function hasTestNow()
800 {
801 return static::getTestNow() !== null;
802 }
803
804 /**
805 * Determine if there is a relative keyword in the time string, this is to
806 * create dates relative to now for test instances. e.g.: next tuesday
807 *
808 * @param string $time
809 *
810 * @return boolean true if there is a keyword, otherwise false
811 */
812 public static function hasRelativeKeywords($time)
813 {
814 // skip common format with a '-' in it
815 if (preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1) {
816 foreach (static::$relativeKeywords as $keyword) {
817 if (stripos($time, $keyword) !== false) {
818 return true;
819 }
820 }
821 }
822
823 return false;
824 }
825
826 ///////////////////////////////////////////////////////////////////
827 /////////////////////// STRING FORMATTING /////////////////////////
828 ///////////////////////////////////////////////////////////////////
829
830 /**
831 * Format the instance with the current locale. You can set the current
832 * locale using setlocale() http://php.net/setlocale.
833 *
834 * @param string $format
835 *
836 * @return string
837 */
838 public function formatLocalized($format)
839 {
840 // Check for Windows to find and replace the %e
841 // modifier correctly
842 if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
843 $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format);
844 }
845
846 return strftime($format, $this->timestamp);
847 }
848
849 /**
850 * Reset the format used to the default when type juggling a Carbon instance to a string
851 *
852 */
853 public static function resetToStringFormat()
854 {
855 static::setToStringFormat(self::DEFAULT_TO_STRING_FORMAT);
856 }
857
858 /**
859 * Set the default format used when type juggling a Carbon instance to a string
860 *
861 * @param string $format
862 */
863 public static function setToStringFormat($format)
864 {
865 static::$toStringFormat = $format;
866 }
867
868 /**
869 * Format the instance as a string using the set format
870 *
871 * @return string
872 */
873 public function __toString()
874 {
875 return $this->format(static::$toStringFormat);
876 }
877
878 /**
879 * Format the instance as date
880 *
881 * @return string
882 */
883 public function toDateString()
884 {
885 return $this->format('Y-m-d');
886 }
887
888 /**
889 * Format the instance as a readable date
890 *
891 * @return string
892 */
893 public function toFormattedDateString()
894 {
895 return $this->format('M j, Y');
896 }
897
898 /**
899 * Format the instance as time
900 *
901 * @return string
902 */
903 public function toTimeString()
904 {
905 return $this->format('H:i:s');
906 }
907
908 /**
909 * Format the instance as date and time
910 *
911 * @return string
912 */
913 public function toDateTimeString()
914 {
915 return $this->format('Y-m-d H:i:s');
916 }
917
918 /**
919 * Format the instance with day, date and time
920 *
921 * @return string
922 */
923 public function toDayDateTimeString()
924 {
925 return $this->format('D, M j, Y g:i A');
926 }
927
928 /**
929 * Format the instance as ATOM
930 *
931 * @return string
932 */
933 public function toAtomString()
934 {
935 return $this->format(self::ATOM);
936 }
937
938 /**
939 * Format the instance as COOKIE
940 *
941 * @return string
942 */
943 public function toCookieString()
944 {
945 return $this->format(self::COOKIE);
946 }
947
948 /**
949 * Format the instance as ISO8601
950 *
951 * @return string
952 */
953 public function toIso8601String()
954 {
955 return $this->format(self::ISO8601);
956 }
957
958 /**
959 * Format the instance as RFC822
960 *
961 * @return string
962 */
963 public function toRfc822String()
964 {
965 return $this->format(self::RFC822);
966 }
967
968 /**
969 * Format the instance as RFC850
970 *
971 * @return string
972 */
973 public function toRfc850String()
974 {
975 return $this->format(self::RFC850);
976 }
977
978 /**
979 * Format the instance as RFC1036
980 *
981 * @return string
982 */
983 public function toRfc1036String()
984 {
985 return $this->format(self::RFC1036);
986 }
987
988 /**
989 * Format the instance as RFC1123
990 *
991 * @return string
992 */
993 public function toRfc1123String()
994 {
995 return $this->format(self::RFC1123);
996 }
997
998 /**
999 * Format the instance as RFC2822
1000 *
1001 * @return string
1002 */
1003 public function toRfc2822String()
1004 {
1005 return $this->format(self::RFC2822);
1006 }
1007
1008 /**
1009 * Format the instance as RFC3339
1010 *
1011 * @return string
1012 */
1013 public function toRfc3339String()
1014 {
1015 return $this->format(self::RFC3339);
1016 }
1017
1018 /**
1019 * Format the instance as RSS
1020 *
1021 * @return string
1022 */
1023 public function toRssString()
1024 {
1025 return $this->format(self::RSS);
1026 }
1027
1028 /**
1029 * Format the instance as W3C
1030 *
1031 * @return string
1032 */
1033 public function toW3cString()
1034 {
1035 return $this->format(self::W3C);
1036 }
1037
1038 ///////////////////////////////////////////////////////////////////
1039 ////////////////////////// COMPARISONS ////////////////////////////
1040 ///////////////////////////////////////////////////////////////////
1041
1042 /**
1043 * Determines if the instance is equal to another
1044 *
1045 * @param Carbon $dt
1046 *
1047 * @return boolean
1048 */
1049 public function eq(Carbon $dt)
1050 {
1051 return $this == $dt;
1052 }
1053
1054 /**
1055 * Determines if the instance is not equal to another
1056 *
1057 * @param Carbon $dt
1058 *
1059 * @return boolean
1060 */
1061 public function ne(Carbon $dt)
1062 {
1063 return !$this->eq($dt);
1064 }
1065
1066 /**
1067 * Determines if the instance is greater (after) than another
1068 *
1069 * @param Carbon $dt
1070 *
1071 * @return boolean
1072 */
1073 public function gt(Carbon $dt)
1074 {
1075 return $this > $dt;
1076 }
1077
1078 /**
1079 * Determines if the instance is greater (after) than or equal to another
1080 *
1081 * @param Carbon $dt
1082 *
1083 * @return boolean
1084 */
1085 public function gte(Carbon $dt)
1086 {
1087 return $this >= $dt;
1088 }
1089
1090 /**
1091 * Determines if the instance is less (before) than another
1092 *
1093 * @param Carbon $dt
1094 *
1095 * @return boolean
1096 */
1097 public function lt(Carbon $dt)
1098 {
1099 return $this < $dt;
1100 }
1101
1102 /**
1103 * Determines if the instance is less (before) or equal to another
1104 *
1105 * @param Carbon $dt
1106 *
1107 * @return boolean
1108 */
1109 public function lte(Carbon $dt)
1110 {
1111 return $this <= $dt;
1112 }
1113
1114 /**
1115 * Determines if the instance is between two others
1116 *
1117 * @param Carbon $dt1
1118 * @param Carbon $dt2
1119 * @param boolean $equal Indicates if a > and < comparison should be used or <= or >=
1120 *
1121 * @return boolean
1122 */
1123 public function between(Carbon $dt1, Carbon $dt2, $equal = true)
1124 {
1125 if ($dt1->gt($dt2)) {
1126 $temp = $dt1;
1127 $dt1 = $dt2;
1128 $dt2 = $temp;
1129 }
1130
1131 if ($equal) {
1132 return $this->gte($dt1) && $this->lte($dt2);
1133 } else {
1134 return $this->gt($dt1) && $this->lt($dt2);
1135 }
1136 }
1137
1138 /**
1139 * Get the minimum instance between a given instance (default now) and the current instance.
1140 *
1141 * @param Carbon $dt
1142 *
1143 * @return static
1144 */
1145 public function min(Carbon $dt = null)
1146 {
1147 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1148
1149 return $this->lt($dt) ? $this : $dt;
1150 }
1151
1152 /**
1153 * Get the maximum instance between a given instance (default now) and the current instance.
1154 *
1155 * @param Carbon $dt
1156 *
1157 * @return static
1158 */
1159 public function max(Carbon $dt = null)
1160 {
1161 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1162
1163 return $this->gt($dt) ? $this : $dt;
1164 }
1165
1166 /**
1167 * Determines if the instance is a weekday
1168 *
1169 * @return boolean
1170 */
1171 public function isWeekday()
1172 {
1173 return ($this->dayOfWeek != self::SUNDAY && $this->dayOfWeek != self::SATURDAY);
1174 }
1175
1176 /**
1177 * Determines if the instance is a weekend day
1178 *
1179 * @return boolean
1180 */
1181 public function isWeekend()
1182 {
1183 return !$this->isWeekDay();
1184 }
1185
1186 /**
1187 * Determines if the instance is yesterday
1188 *
1189 * @return boolean
1190 */
1191 public function isYesterday()
1192 {
1193 return $this->toDateString() === static::yesterday($this->tz)->toDateString();
1194 }
1195
1196 /**
1197 * Determines if the instance is today
1198 *
1199 * @return boolean
1200 */
1201 public function isToday()
1202 {
1203 return $this->toDateString() === static::now($this->tz)->toDateString();
1204 }
1205
1206 /**
1207 * Determines if the instance is tomorrow
1208 *
1209 * @return boolean
1210 */
1211 public function isTomorrow()
1212 {
1213 return $this->toDateString() === static::tomorrow($this->tz)->toDateString();
1214 }
1215
1216 /**
1217 * Determines if the instance is in the future, ie. greater (after) than now
1218 *
1219 * @return boolean
1220 */
1221 public function isFuture()
1222 {
1223 return $this->gt(static::now($this->tz));
1224 }
1225
1226 /**
1227 * Determines if the instance is in the past, ie. less (before) than now
1228 *
1229 * @return boolean
1230 */
1231 public function isPast()
1232 {
1233 return $this->lt(static::now($this->tz));
1234 }
1235
1236 /**
1237 * Determines if the instance is a leap year
1238 *
1239 * @return boolean
1240 */
1241 public function isLeapYear()
1242 {
1243 return $this->format('L') == '1';
1244 }
1245
1246 /**
1247 * Checks if the passed in date is the same day as the instance current day.
1248 *
1249 * @param Carbon $dt
1250 * @return boolean
1251 */
1252 public function isSameDay(Carbon $dt)
1253 {
1254 return $this->toDateString() === $dt->toDateString();
1255 }
1256
1257 ///////////////////////////////////////////////////////////////////
1258 /////////////////// ADDITIONS AND SUBSTRACTIONS ///////////////////
1259 ///////////////////////////////////////////////////////////////////
1260
1261 /**
1262 * Add years to the instance. Positive $value travel forward while
1263 * negative $value travel into the past.
1264 *
1265 * @param integer $value
1266 *
1267 * @return static
1268 */
1269 public function addYears($value)
1270 {
1271 return $this->modify((int) $value . ' year');
1272 }
1273
1274 /**
1275 * Add a year to the instance
1276 *
1277 * @return static
1278 */
1279 public function addYear()
1280 {
1281 return $this->addYears(1);
1282 }
1283
1284 /**
1285 * Remove a year from the instance
1286 *
1287 * @return static
1288 */
1289 public function subYear()
1290 {
1291 return $this->addYears(-1);
1292 }
1293
1294 /**
1295 * Remove years from the instance.
1296 *
1297 * @param integer $value
1298 *
1299 * @return static
1300 */
1301 public function subYears($value)
1302 {
1303 return $this->addYears(-1 * $value);
1304 }
1305
1306 /**
1307 * Add months to the instance. Positive $value travels forward while
1308 * negative $value travels into the past.
1309 *
1310 * @param integer $value
1311 *
1312 * @return static
1313 */
1314 public function addMonths($value)
1315 {
1316 return $this->modify((int) $value . ' month');
1317 }
1318
1319 /**
1320 * Add a month to the instance
1321 *
1322 * @return static
1323 */
1324 public function addMonth()
1325 {
1326 return $this->addMonths(1);
1327 }
1328
1329 /**
1330 * Remove a month from the instance
1331 *
1332 * @return static
1333 */
1334 public function subMonth()
1335 {
1336 return $this->addMonths(-1);
1337 }
1338
1339 /**
1340 * Remove months from the instance
1341 *
1342 * @param integer $value
1343 *
1344 * @return static
1345 */
1346 public function subMonths($value)
1347 {
1348 return $this->addMonths(-1 * $value);
1349 }
1350
1351 /**
1352 * Add days to the instance. Positive $value travels forward while
1353 * negative $value travels into the past.
1354 *
1355 * @param integer $value
1356 *
1357 * @return static
1358 */
1359 public function addDays($value)
1360 {
1361 return $this->modify((int) $value . ' day');
1362 }
1363
1364 /**
1365 * Add a day to the instance
1366 *
1367 * @return static
1368 */
1369 public function addDay()
1370 {
1371 return $this->addDays(1);
1372 }
1373
1374 /**
1375 * Remove a day from the instance
1376 *
1377 * @return static
1378 */
1379 public function subDay()
1380 {
1381 return $this->addDays(-1);
1382 }
1383
1384 /**
1385 * Remove days from the instance
1386 *
1387 * @param integer $value
1388 *
1389 * @return static
1390 */
1391 public function subDays($value)
1392 {
1393 return $this->addDays(-1 * $value);
1394 }
1395
1396 /**
1397 * Add weekdays to the instance. Positive $value travels forward while
1398 * negative $value travels into the past.
1399 *
1400 * @param integer $value
1401 *
1402 * @return static
1403 */
1404 public function addWeekdays($value)
1405 {
1406 return $this->modify((int) $value . ' weekday');
1407 }
1408
1409 /**
1410 * Add a weekday to the instance
1411 *
1412 * @return static
1413 */
1414 public function addWeekday()
1415 {
1416 return $this->addWeekdays(1);
1417 }
1418
1419 /**
1420 * Remove a weekday from the instance
1421 *
1422 * @return static
1423 */
1424 public function subWeekday()
1425 {
1426 return $this->addWeekdays(-1);
1427 }
1428
1429 /**
1430 * Remove weekdays from the instance
1431 *
1432 * @param integer $value
1433 *
1434 * @return static
1435 */
1436 public function subWeekdays($value)
1437 {
1438 return $this->addWeekdays(-1 * $value);
1439 }
1440
1441 /**
1442 * Add weeks to the instance. Positive $value travels forward while
1443 * negative $value travels into the past.
1444 *
1445 * @param integer $value
1446 *
1447 * @return static
1448 */
1449 public function addWeeks($value)
1450 {
1451 return $this->modify((int) $value . ' week');
1452 }
1453
1454 /**
1455 * Add a week to the instance
1456 *
1457 * @return static
1458 */
1459 public function addWeek()
1460 {
1461 return $this->addWeeks(1);
1462 }
1463
1464 /**
1465 * Remove a week from the instance
1466 *
1467 * @return static
1468 */
1469 public function subWeek()
1470 {
1471 return $this->addWeeks(-1);
1472 }
1473
1474 /**
1475 * Remove weeks to the instance
1476 *
1477 * @param integer $value
1478 *
1479 * @return static
1480 */
1481 public function subWeeks($value)
1482 {
1483 return $this->addWeeks(-1 * $value);
1484 }
1485
1486 /**
1487 * Add hours to the instance. Positive $value travels forward while
1488 * negative $value travels into the past.
1489 *
1490 * @param integer $value
1491 *
1492 * @return static
1493 */
1494 public function addHours($value)
1495 {
1496 return $this->modify((int) $value . ' hour');
1497 }
1498
1499 /**
1500 * Add an hour to the instance
1501 *
1502 * @return static
1503 */
1504 public function addHour()
1505 {
1506 return $this->addHours(1);
1507 }
1508
1509 /**
1510 * Remove an hour from the instance
1511 *
1512 * @return static
1513 */
1514 public function subHour()
1515 {
1516 return $this->addHours(-1);
1517 }
1518
1519 /**
1520 * Remove hours from the instance
1521 *
1522 * @param integer $value
1523 *
1524 * @return static
1525 */
1526 public function subHours($value)
1527 {
1528 return $this->addHours(-1 * $value);
1529 }
1530
1531 /**
1532 * Add minutes to the instance. Positive $value travels forward while
1533 * negative $value travels into the past.
1534 *
1535 * @param integer $value
1536 *
1537 * @return static
1538 */
1539 public function addMinutes($value)
1540 {
1541 return $this->modify((int) $value . ' minute');
1542 }
1543
1544 /**
1545 * Add a minute to the instance
1546 *
1547 * @return static
1548 */
1549 public function addMinute()
1550 {
1551 return $this->addMinutes(1);
1552 }
1553
1554 /**
1555 * Remove a minute from the instance
1556 *
1557 * @return static
1558 */
1559 public function subMinute()
1560 {
1561 return $this->addMinutes(-1);
1562 }
1563
1564 /**
1565 * Remove minutes from the instance
1566 *
1567 * @param integer $value
1568 *
1569 * @return static
1570 */
1571 public function subMinutes($value)
1572 {
1573 return $this->addMinutes(-1 * $value);
1574 }
1575
1576 /**
1577 * Add seconds to the instance. Positive $value travels forward while
1578 * negative $value travels into the past.
1579 *
1580 * @param integer $value
1581 *
1582 * @return static
1583 */
1584 public function addSeconds($value)
1585 {
1586 return $this->modify((int) $value . ' second');
1587 }
1588
1589 /**
1590 * Add a second to the instance
1591 *
1592 * @return static
1593 */
1594 public function addSecond()
1595 {
1596 return $this->addSeconds(1);
1597 }
1598
1599 /**
1600 * Remove a second from the instance
1601 *
1602 * @return static
1603 */
1604 public function subSecond()
1605 {
1606 return $this->addSeconds(-1);
1607 }
1608
1609 /**
1610 * Remove seconds from the instance
1611 *
1612 * @param integer $value
1613 *
1614 * @return static
1615 */
1616 public function subSeconds($value)
1617 {
1618 return $this->addSeconds(-1 * $value);
1619 }
1620
1621 ///////////////////////////////////////////////////////////////////
1622 /////////////////////////// DIFFERENCES ///////////////////////////
1623 ///////////////////////////////////////////////////////////////////
1624
1625 /**
1626 * Get the difference in years
1627 *
1628 * @param Carbon $dt
1629 * @param boolean $abs Get the absolute of the difference
1630 *
1631 * @return integer
1632 */
1633 public function diffInYears(Carbon $dt = null, $abs = true)
1634 {
1635 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1636
1637 return (int) $this->diff($dt, $abs)->format('%r%y');
1638 }
1639
1640 /**
1641 * Get the difference in months
1642 *
1643 * @param Carbon $dt
1644 * @param boolean $abs Get the absolute of the difference
1645 *
1646 * @return integer
1647 */
1648 public function diffInMonths(Carbon $dt = null, $abs = true)
1649 {
1650 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1651
1652 return $this->diffInYears($dt, $abs) * self::MONTHS_PER_YEAR + $this->diff($dt, $abs)->format('%r%m');
1653 }
1654
1655 /**
1656 * Get the difference in weeks
1657 *
1658 * @param Carbon $dt
1659 * @param boolean $abs Get the absolute of the difference
1660 *
1661 * @return integer
1662 */
1663 public function diffInWeeks(Carbon $dt = null, $abs = true)
1664 {
1665 return (int) ($this->diffInDays($dt, $abs) / self::DAYS_PER_WEEK);
1666 }
1667
1668 /**
1669 * Get the difference in days
1670 *
1671 * @param Carbon $dt
1672 * @param boolean $abs Get the absolute of the difference
1673 *
1674 * @return integer
1675 */
1676 public function diffInDays(Carbon $dt = null, $abs = true)
1677 {
1678 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1679
1680 return (int) $this->diff($dt, $abs)->format('%r%a');
1681 }
1682
1683 /**
1684 * Get the difference in days using a filter closure
1685 *
1686 * @param Closure $callback
1687 * @param Carbon $dt
1688 * @param boolean $abs Get the absolute of the difference
1689 *
1690 * @return int
1691 */
1692 public function diffInDaysFiltered(Closure $callback, Carbon $dt = null, $abs = true)
1693 {
1694 $start = $this;
1695 $end = ($dt === null) ? static::now($this->tz) : $dt;
1696 $inverse = false;
1697
1698 if ($end < $start) {
1699 $start = $end;
1700 $end = $this;
1701 $inverse = true;
1702 }
1703
1704 $period = new DatePeriod($start, new DateInterval('P1D'), $end);
1705 $days = array_filter(iterator_to_array($period), function (DateTime $date) use ($callback) {
1706 return call_user_func($callback, Carbon::instance($date));
1707 });
1708
1709 $diff = count($days);
1710
1711 return $inverse && !$abs ? -$diff : $diff;
1712 }
1713
1714 /**
1715 * Get the difference in weekdays
1716 *
1717 * @param Carbon $dt
1718 * @param boolean $abs Get the absolute of the difference
1719 *
1720 * @return int
1721 */
1722 public function diffInWeekdays(Carbon $dt = null, $abs = true)
1723 {
1724 return $this->diffInDaysFiltered(function (Carbon $date) {
1725 return $date->isWeekday();
1726 }, $dt, $abs);
1727 }
1728
1729 /**
1730 * Get the difference in weekend days using a filter
1731 *
1732 * @param Carbon $dt
1733 * @param boolean $abs Get the absolute of the difference
1734 *
1735 * @return int
1736 */
1737 public function diffInWeekendDays(Carbon $dt = null, $abs = true)
1738 {
1739 return $this->diffInDaysFiltered(function (Carbon $date) {
1740 return $date->isWeekend();
1741 }, $dt, $abs);
1742 }
1743
1744 /**
1745 * Get the difference in hours
1746 *
1747 * @param Carbon $dt
1748 * @param boolean $abs Get the absolute of the difference
1749 *
1750 * @return integer
1751 */
1752 public function diffInHours(Carbon $dt = null, $abs = true)
1753 {
1754 return (int) ($this->diffInSeconds($dt, $abs) / self::SECONDS_PER_MINUTE / self::MINUTES_PER_HOUR);
1755 }
1756
1757 /**
1758 * Get the difference in minutes
1759 *
1760 * @param Carbon $dt
1761 * @param boolean $abs Get the absolute of the difference
1762 *
1763 * @return integer
1764 */
1765 public function diffInMinutes(Carbon $dt = null, $abs = true)
1766 {
1767 return (int) ($this->diffInSeconds($dt, $abs) / self::SECONDS_PER_MINUTE);
1768 }
1769
1770 /**
1771 * Get the difference in seconds
1772 *
1773 * @param Carbon $dt
1774 * @param boolean $abs Get the absolute of the difference
1775 *
1776 * @return integer
1777 */
1778 public function diffInSeconds(Carbon $dt = null, $abs = true)
1779 {
1780 $value = (($dt === null) ? time() : $dt->getTimestamp()) - $this->getTimestamp();
1781
1782 return $abs ? abs($value) : $value;
1783 }
1784
1785 /**
1786 * Get the difference in a human readable format.
1787 *
1788 * When comparing a value in the past to default now:
1789 * 1 hour ago
1790 * 5 months ago
1791 *
1792 * When comparing a value in the future to default now:
1793 * 1 hour from now
1794 * 5 months from now
1795 *
1796 * When comparing a value in the past to another value:
1797 * 1 hour before
1798 * 5 months before
1799 *
1800 * When comparing a value in the future to another value:
1801 * 1 hour after
1802 * 5 months after
1803 *
1804 * @param Carbon $other
1805 *
1806 * @return string
1807 */
1808 public function diffForHumans(Carbon $other = null)
1809 {
1810 $isNow = $other === null;
1811
1812 if ($isNow) {
1813 $other = static::now($this->tz);
1814 }
1815
1816 $isFuture = $this->gt($other);
1817
1818 $delta = $other->diffInSeconds($this);
1819
1820 // a little weeks per month, 365 days per year... good enough!!
1821 $divs = array(
1822 'second' => self::SECONDS_PER_MINUTE,
1823 'minute' => self::MINUTES_PER_HOUR,
1824 'hour' => self::HOURS_PER_DAY,
1825 'day' => self::DAYS_PER_WEEK,
1826 'week' => 30 / self::DAYS_PER_WEEK,
1827 'month' => self::MONTHS_PER_YEAR
1828 );
1829
1830 $unit = 'year';
1831
1832 foreach ($divs as $divUnit => $divValue) {
1833 if ($delta < $divValue) {
1834 $unit = $divUnit;
1835 break;
1836 }
1837
1838 $delta = $delta / $divValue;
1839 }
1840
1841 $delta = (int) $delta;
1842
1843 if ($delta == 0) {
1844 $delta = 1;
1845 }
1846
1847 $txt = $delta . ' ' . $unit;
1848 $txt .= $delta == 1 ? '' : 's';
1849
1850 if ($isNow) {
1851 if ($isFuture) {
1852 return $txt . ' from now';
1853 }
1854
1855 return $txt . ' ago';
1856 }
1857
1858 if ($isFuture) {
1859 return $txt . ' after';
1860 }
1861
1862 return $txt . ' before';
1863 }
1864
1865 ///////////////////////////////////////////////////////////////////
1866 //////////////////////////// MODIFIERS ////////////////////////////
1867 ///////////////////////////////////////////////////////////////////
1868
1869 /**
1870 * Resets the time to 00:00:00
1871 *
1872 * @return static
1873 */
1874 public function startOfDay()
1875 {
1876 return $this->hour(0)->minute(0)->second(0);
1877 }
1878
1879 /**
1880 * Resets the time to 23:59:59
1881 *
1882 * @return static
1883 */
1884 public function endOfDay()
1885 {
1886 return $this->hour(23)->minute(59)->second(59);
1887 }
1888
1889 /**
1890 * Resets the date to the first day of the month and the time to 00:00:00
1891 *
1892 * @return static
1893 */
1894 public function startOfMonth()
1895 {
1896 return $this->startOfDay()->day(1);
1897 }
1898
1899 /**
1900 * Resets the date to end of the month and time to 23:59:59
1901 *
1902 * @return static
1903 */
1904 public function endOfMonth()
1905 {
1906 return $this->day($this->daysInMonth)->endOfDay();
1907 }
1908
1909 /**
1910 * Resets the date to the first day of the year and the time to 00:00:00
1911 *
1912 * @return static
1913 */
1914 public function startOfYear()
1915 {
1916 return $this->month(1)->startOfMonth();
1917 }
1918
1919 /**
1920 * Resets the date to end of the year and time to 23:59:59
1921 *
1922 * @return static
1923 */
1924 public function endOfYear()
1925 {
1926 return $this->month(self::MONTHS_PER_YEAR)->endOfMonth();
1927 }
1928
1929 /**
1930 * Resets the date to the first day of the decade and the time to 00:00:00
1931 *
1932 * @return static
1933 */
1934 public function startOfDecade()
1935 {
1936 return $this->startOfYear()->year($this->year - $this->year % self::YEARS_PER_DECADE);
1937 }
1938
1939 /**
1940 * Resets the date to end of the decade and time to 23:59:59
1941 *
1942 * @return static
1943 */
1944 public function endOfDecade()
1945 {
1946 return $this->endOfYear()->year($this->year - $this->year % self::YEARS_PER_DECADE + self::YEARS_PER_DECADE - 1);
1947 }
1948
1949 /**
1950 * Resets the date to the first day of the century and the time to 00:00:00
1951 *
1952 * @return static
1953 */
1954 public function startOfCentury()
1955 {
1956 return $this->startOfYear()->year($this->year - $this->year % self::YEARS_PER_CENTURY);
1957 }
1958
1959 /**
1960 * Resets the date to end of the century and time to 23:59:59
1961 *
1962 * @return static
1963 */
1964 public function endOfCentury()
1965 {
1966 return $this->endOfYear()->year($this->year - $this->year % self::YEARS_PER_CENTURY + self::YEARS_PER_CENTURY - 1);
1967 }
1968
1969 /**
1970 * Resets the date to the first day of the ISO-8601 week (Monday) and the time to 00:00:00
1971 *
1972 * @return static
1973 */
1974 public function startOfWeek()
1975 {
1976 if ($this->dayOfWeek != self::MONDAY) $this->previous(self::MONDAY);
1977 return $this->startOfDay();
1978 }
1979
1980 /**
1981 * Resets the date to end of the ISO-8601 week (Sunday) and time to 23:59:59
1982 *
1983 * @return static
1984 */
1985 public function endOfWeek()
1986 {
1987 if ($this->dayOfWeek != self::SUNDAY) $this->next(self::SUNDAY);
1988 return $this->endOfDay();
1989 }
1990
1991 /**
1992 * Modify to the next occurance of a given day of the week.
1993 * If no dayOfWeek is provided, modify to the next occurance
1994 * of the current day of the week. Use the supplied consts
1995 * to indicate the desired dayOfWeek, ex. static::MONDAY.
1996 *
1997 * @param int $dayOfWeek
1998 *
1999 * @return mixed
2000 */
2001 public function next($dayOfWeek = null)
2002 {
2003 if ($dayOfWeek === null) {
2004 $dayOfWeek = $this->dayOfWeek;
2005 }
2006
2007 return $this->startOfDay()->modify('next ' . self::$days[$dayOfWeek]);
2008 }
2009
2010 /**
2011 * Modify to the previous occurance of a given day of the week.
2012 * If no dayOfWeek is provided, modify to the previous occurance
2013 * of the current day of the week. Use the supplied consts
2014 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2015 *
2016 * @param int $dayOfWeek
2017 *
2018 * @return mixed
2019 */
2020 public function previous($dayOfWeek = null)
2021 {
2022 if ($dayOfWeek === null) {
2023 $dayOfWeek = $this->dayOfWeek;
2024 }
2025
2026 return $this->startOfDay()->modify('last ' . self::$days[$dayOfWeek]);
2027 }
2028
2029 /**
2030 * Modify to the first occurance of a given day of the week
2031 * in the current month. If no dayOfWeek is provided, modify to the
2032 * first day of the current month. Use the supplied consts
2033 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2034 *
2035 * @param int $dayOfWeek
2036 *
2037 * @return mixed
2038 */
2039 public function firstOfMonth($dayOfWeek = null)
2040 {
2041 $this->startOfDay();
2042
2043 if ($dayOfWeek === null) {
2044 return $this->day(1);
2045 }
2046
2047 return $this->modify('first ' . self::$days[$dayOfWeek] . ' of ' . $this->format('F') . ' ' . $this->year);
2048 }
2049
2050 /**
2051 * Modify to the last occurance of a given day of the week
2052 * in the current month. If no dayOfWeek is provided, modify to the
2053 * last day of the current month. Use the supplied consts
2054 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2055 *
2056 * @param int $dayOfWeek
2057 *
2058 * @return mixed
2059 */
2060 public function lastOfMonth($dayOfWeek = null)
2061 {
2062 $this->startOfDay();
2063
2064 if ($dayOfWeek === null) {
2065 return $this->day($this->daysInMonth);
2066 }
2067
2068 return $this->modify('last ' . self::$days[$dayOfWeek] . ' of ' . $this->format('F') . ' ' . $this->year);
2069 }
2070
2071 /**
2072 * Modify to the given occurance of a given day of the week
2073 * in the current month. If the calculated occurance is outside the scope
2074 * of the current month, then return false and no modifications are made.
2075 * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY.
2076 *
2077 * @param int $nth
2078 * @param int $dayOfWeek
2079 *
2080 * @return mixed
2081 */
2082 public function nthOfMonth($nth, $dayOfWeek)
2083 {
2084 $dt = $this->copy()->firstOfMonth();
2085 $check = $dt->format('Y-m');
2086 $dt->modify('+' . $nth . ' ' . self::$days[$dayOfWeek]);
2087
2088 return ($dt->format('Y-m') === $check) ? $this->modify($dt) : false;
2089 }
2090
2091 /**
2092 * Modify to the first occurance of a given day of the week
2093 * in the current quarter. If no dayOfWeek is provided, modify to the
2094 * first day of the current quarter. Use the supplied consts
2095 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2096 *
2097 * @param int $dayOfWeek
2098 *
2099 * @return mixed
2100 */
2101 public function firstOfQuarter($dayOfWeek = null)
2102 {
2103 return $this->day(1)->month($this->quarter * 3 - 2)->firstOfMonth($dayOfWeek);
2104 }
2105
2106 /**
2107 * Modify to the last occurance of a given day of the week
2108 * in the current quarter. If no dayOfWeek is provided, modify to the
2109 * last day of the current quarter. Use the supplied consts
2110 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2111 *
2112 * @param int $dayOfWeek
2113 *
2114 * @return mixed
2115 */
2116 public function lastOfQuarter($dayOfWeek = null)
2117 {
2118 return $this->day(1)->month($this->quarter * 3)->lastOfMonth($dayOfWeek);
2119 }
2120
2121 /**
2122 * Modify to the given occurance of a given day of the week
2123 * in the current quarter. If the calculated occurance is outside the scope
2124 * of the current quarter, then return false and no modifications are made.
2125 * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY.
2126 *
2127 * @param int $nth
2128 * @param int $dayOfWeek
2129 *
2130 * @return mixed
2131 */
2132 public function nthOfQuarter($nth, $dayOfWeek)
2133 {
2134 $dt = $this->copy()->day(1)->month($this->quarter * 3);
2135 $last_month = $dt->month;
2136 $year = $dt->year;
2137 $dt->firstOfQuarter()->modify('+' . $nth . ' ' . self::$days[$dayOfWeek]);
2138
2139 return ($last_month < $dt->month || $year !== $dt->year) ? false : $this->modify($dt);
2140 }
2141
2142 /**
2143 * Modify to the first occurance of a given day of the week
2144 * in the current year. If no dayOfWeek is provided, modify to the
2145 * first day of the current year. Use the supplied consts
2146 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2147 *
2148 * @param int $dayOfWeek
2149 *
2150 * @return mixed
2151 */
2152 public function firstOfYear($dayOfWeek = null)
2153 {
2154 return $this->month(1)->firstOfMonth($dayOfWeek);
2155 }
2156
2157 /**
2158 * Modify to the last occurance of a given day of the week
2159 * in the current year. If no dayOfWeek is provided, modify to the
2160 * last day of the current year. Use the supplied consts
2161 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2162 *
2163 * @param int $dayOfWeek
2164 *
2165 * @return mixed
2166 */
2167 public function lastOfYear($dayOfWeek = null)
2168 {
2169 return $this->month(self::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek);
2170 }
2171
2172 /**
2173 * Modify to the given occurance of a given day of the week
2174 * in the current year. If the calculated occurance is outside the scope
2175 * of the current year, then return false and no modifications are made.
2176 * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY.
2177 *
2178 * @param int $nth
2179 * @param int $dayOfWeek
2180 *
2181 * @return mixed
2182 */
2183 public function nthOfYear($nth, $dayOfWeek)
2184 {
2185 $dt = $this->copy()->firstOfYear()->modify('+' . $nth . ' ' . self::$days[$dayOfWeek]);
2186
2187 return $this->year == $dt->year ? $this->modify($dt) : false;
2188 }
2189
2190 /**
2191 * Modify the current instance to the average of a given instance (default now) and the current instance.
2192 *
2193 * @param Carbon $dt
2194 *
2195 * @return static
2196 */
2197 public function average(Carbon $dt = null)
2198 {
2199 $dt = ($dt === null) ? static::now($this->tz) : $dt;
2200
2201 return $this->addSeconds((int) ($this->diffInSeconds($dt, false) / 2));
2202 }
2203
2204 /**
2205 * Check if its the birthday. Compares the date/month values of the two dates.
2206 * @param Carbon $dt
2207 * @return boolean
2208 */
2209 public function isBirthday(Carbon $dt)
2210 {
2211 return $this->month === $dt->month && $this->day === $dt->day;
2212 }
2213 }