PluginProbe
Stream – Activity Log & Audit Trail / 3.8.0
Stream – Activity Log & Audit Trail v3.8.0
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.8.0, at includes/lib/Carbon.php

2,215 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) ? gmdate('Y') : $year;
316 $month = ($month === null) ? gmdate('n') : $month;
317 $day = ($day === null) ? gmdate('j') : $day;
318
319 if ($hour === null) {
320 $hour = gmdate('G');
321 $minute = ($minute === null) ? gmdate('i') : $minute;
322 $second = ($second === null) ? gmdate('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 * @param integer $microseconds
679 *
680 * @return static
681 */
682 public function setTime($hour, $minute, $second = 0, $microseconds = 0 )
683 {
684 parent::setTime($hour, $minute, $second, $microseconds );
685
686 return $this;
687 }
688
689 /**
690 * Set the date and time all together
691 *
692 * @param integer $year
693 * @param integer $month
694 * @param integer $day
695 * @param integer $hour
696 * @param integer $minute
697 * @param integer $second
698 *
699 * @return static
700 */
701 public function setDateTime($year, $month, $day, $hour, $minute, $second = 0)
702 {
703 return $this->setDate($year, $month, $day)->setTime($hour, $minute, $second);
704 }
705
706 /**
707 * Set the instance's timestamp
708 *
709 * @param integer $value
710 *
711 * @return static
712 */
713 public function timestamp($value)
714 {
715 $this->timestamp = $value;
716
717 return $this;
718 }
719
720 /**
721 * Alias for setTimezone()
722 *
723 * @param DateTimeZone|string $value
724 *
725 * @return static
726 */
727 public function timezone($value)
728 {
729 return $this->setTimezone($value);
730 }
731
732 /**
733 * Alias for setTimezone()
734 *
735 * @param DateTimeZone|string $value
736 *
737 * @return static
738 */
739 public function tz($value)
740 {
741 return $this->setTimezone($value);
742 }
743
744 /**
745 * Set the instance's timezone from a string or object
746 *
747 * @param DateTimeZone|string $value
748 *
749 * @return static
750 */
751 public function setTimezone($value)
752 {
753 parent::setTimezone(static::safeCreateDateTimeZone($value));
754
755 return $this;
756 }
757
758 ///////////////////////////////////////////////////////////////////
759 ///////////////////////// TESTING AIDS ////////////////////////////
760 ///////////////////////////////////////////////////////////////////
761
762 /**
763 * Set a Carbon instance (real or mock) to be returned when a "now"
764 * instance is created. The provided instance will be returned
765 * specifically under the following conditions:
766 * - A call to the static now() method, ex. Carbon::now()
767 * - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
768 * - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
769 *
770 * Note the timezone parameter was left out of the examples above and
771 * has no affect as the mock value will be returned regardless of its value.
772 *
773 * To clear the test instance call this method using the default
774 * parameter of null.
775 *
776 * @param Carbon $testNow
777 */
778 public static function setTestNow(Carbon $testNow = null)
779 {
780 static::$testNow = $testNow;
781 }
782
783 /**
784 * Get the Carbon instance (real or mock) to be returned when a "now"
785 * instance is created.
786 *
787 * @return static the current instance used for testing
788 */
789 public static function getTestNow()
790 {
791 return static::$testNow;
792 }
793
794 /**
795 * Determine if there is a valid test instance set. A valid test instance
796 * is anything that is not null.
797 *
798 * @return boolean true if there is a test instance, otherwise false
799 */
800 public static function hasTestNow()
801 {
802 return static::getTestNow() !== null;
803 }
804
805 /**
806 * Determine if there is a relative keyword in the time string, this is to
807 * create dates relative to now for test instances. e.g.: next tuesday
808 *
809 * @param string $time
810 *
811 * @return boolean true if there is a keyword, otherwise false
812 */
813 public static function hasRelativeKeywords($time)
814 {
815 // skip common format with a '-' in it
816 if (preg_match('/[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}/', $time) !== 1) {
817 foreach (static::$relativeKeywords as $keyword) {
818 if (stripos($time, $keyword) !== false) {
819 return true;
820 }
821 }
822 }
823
824 return false;
825 }
826
827 ///////////////////////////////////////////////////////////////////
828 /////////////////////// STRING FORMATTING /////////////////////////
829 ///////////////////////////////////////////////////////////////////
830
831 /**
832 * Format the instance with the current locale. You can set the current
833 * locale using setlocale() http://php.net/setlocale.
834 *
835 * @param string $format
836 *
837 * @return string
838 */
839 public function formatLocalized($format)
840 {
841 // Check for Windows to find and replace the %e
842 // modifier correctly
843 if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
844 $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format);
845 }
846
847 return strftime($format, $this->timestamp);
848 }
849
850 /**
851 * Reset the format used to the default when type juggling a Carbon instance to a string
852 *
853 */
854 public static function resetToStringFormat()
855 {
856 static::setToStringFormat(self::DEFAULT_TO_STRING_FORMAT);
857 }
858
859 /**
860 * Set the default format used when type juggling a Carbon instance to a string
861 *
862 * @param string $format
863 */
864 public static function setToStringFormat($format)
865 {
866 static::$toStringFormat = $format;
867 }
868
869 /**
870 * Format the instance as a string using the set format
871 *
872 * @return string
873 */
874 public function __toString()
875 {
876 return $this->format(static::$toStringFormat);
877 }
878
879 /**
880 * Format the instance as date
881 *
882 * @return string
883 */
884 public function toDateString()
885 {
886 return $this->format('Y-m-d');
887 }
888
889 /**
890 * Format the instance as a readable date
891 *
892 * @return string
893 */
894 public function toFormattedDateString()
895 {
896 return $this->format('M j, Y');
897 }
898
899 /**
900 * Format the instance as time
901 *
902 * @return string
903 */
904 public function toTimeString()
905 {
906 return $this->format('H:i:s');
907 }
908
909 /**
910 * Format the instance as date and time
911 *
912 * @return string
913 */
914 public function toDateTimeString()
915 {
916 return $this->format('Y-m-d H:i:s');
917 }
918
919 /**
920 * Format the instance with day, date and time
921 *
922 * @return string
923 */
924 public function toDayDateTimeString()
925 {
926 return $this->format('D, M j, Y g:i A');
927 }
928
929 /**
930 * Format the instance as ATOM
931 *
932 * @return string
933 */
934 public function toAtomString()
935 {
936 return $this->format(self::ATOM);
937 }
938
939 /**
940 * Format the instance as COOKIE
941 *
942 * @return string
943 */
944 public function toCookieString()
945 {
946 return $this->format(self::COOKIE);
947 }
948
949 /**
950 * Format the instance as ISO8601
951 *
952 * @return string
953 */
954 public function toIso8601String()
955 {
956 return $this->format(self::ISO8601);
957 }
958
959 /**
960 * Format the instance as RFC822
961 *
962 * @return string
963 */
964 public function toRfc822String()
965 {
966 return $this->format(self::RFC822);
967 }
968
969 /**
970 * Format the instance as RFC850
971 *
972 * @return string
973 */
974 public function toRfc850String()
975 {
976 return $this->format(self::RFC850);
977 }
978
979 /**
980 * Format the instance as RFC1036
981 *
982 * @return string
983 */
984 public function toRfc1036String()
985 {
986 return $this->format(self::RFC1036);
987 }
988
989 /**
990 * Format the instance as RFC1123
991 *
992 * @return string
993 */
994 public function toRfc1123String()
995 {
996 return $this->format(self::RFC1123);
997 }
998
999 /**
1000 * Format the instance as RFC2822
1001 *
1002 * @return string
1003 */
1004 public function toRfc2822String()
1005 {
1006 return $this->format(self::RFC2822);
1007 }
1008
1009 /**
1010 * Format the instance as RFC3339
1011 *
1012 * @return string
1013 */
1014 public function toRfc3339String()
1015 {
1016 return $this->format(self::RFC3339);
1017 }
1018
1019 /**
1020 * Format the instance as RSS
1021 *
1022 * @return string
1023 */
1024 public function toRssString()
1025 {
1026 return $this->format(self::RSS);
1027 }
1028
1029 /**
1030 * Format the instance as W3C
1031 *
1032 * @return string
1033 */
1034 public function toW3cString()
1035 {
1036 return $this->format(self::W3C);
1037 }
1038
1039 ///////////////////////////////////////////////////////////////////
1040 ////////////////////////// COMPARISONS ////////////////////////////
1041 ///////////////////////////////////////////////////////////////////
1042
1043 /**
1044 * Determines if the instance is equal to another
1045 *
1046 * @param Carbon $dt
1047 *
1048 * @return boolean
1049 */
1050 public function eq(Carbon $dt)
1051 {
1052 return $this == $dt;
1053 }
1054
1055 /**
1056 * Determines if the instance is not equal to another
1057 *
1058 * @param Carbon $dt
1059 *
1060 * @return boolean
1061 */
1062 public function ne(Carbon $dt)
1063 {
1064 return !$this->eq($dt);
1065 }
1066
1067 /**
1068 * Determines if the instance is greater (after) than another
1069 *
1070 * @param Carbon $dt
1071 *
1072 * @return boolean
1073 */
1074 public function gt(Carbon $dt)
1075 {
1076 return $this > $dt;
1077 }
1078
1079 /**
1080 * Determines if the instance is greater (after) than or equal to another
1081 *
1082 * @param Carbon $dt
1083 *
1084 * @return boolean
1085 */
1086 public function gte(Carbon $dt)
1087 {
1088 return $this >= $dt;
1089 }
1090
1091 /**
1092 * Determines if the instance is less (before) than another
1093 *
1094 * @param Carbon $dt
1095 *
1096 * @return boolean
1097 */
1098 public function lt(Carbon $dt)
1099 {
1100 return $this < $dt;
1101 }
1102
1103 /**
1104 * Determines if the instance is less (before) or equal to another
1105 *
1106 * @param Carbon $dt
1107 *
1108 * @return boolean
1109 */
1110 public function lte(Carbon $dt)
1111 {
1112 return $this <= $dt;
1113 }
1114
1115 /**
1116 * Determines if the instance is between two others
1117 *
1118 * @param Carbon $dt1
1119 * @param Carbon $dt2
1120 * @param boolean $equal Indicates if a > and < comparison should be used or <= or >=
1121 *
1122 * @return boolean
1123 */
1124 public function between(Carbon $dt1, Carbon $dt2, $equal = true)
1125 {
1126 if ($dt1->gt($dt2)) {
1127 $temp = $dt1;
1128 $dt1 = $dt2;
1129 $dt2 = $temp;
1130 }
1131
1132 if ($equal) {
1133 return $this->gte($dt1) && $this->lte($dt2);
1134 } else {
1135 return $this->gt($dt1) && $this->lt($dt2);
1136 }
1137 }
1138
1139 /**
1140 * Get the minimum instance between a given instance (default now) and the current instance.
1141 *
1142 * @param Carbon $dt
1143 *
1144 * @return static
1145 */
1146 public function min(Carbon $dt = null)
1147 {
1148 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1149
1150 return $this->lt($dt) ? $this : $dt;
1151 }
1152
1153 /**
1154 * Get the maximum instance between a given instance (default now) and the current instance.
1155 *
1156 * @param Carbon $dt
1157 *
1158 * @return static
1159 */
1160 public function max(Carbon $dt = null)
1161 {
1162 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1163
1164 return $this->gt($dt) ? $this : $dt;
1165 }
1166
1167 /**
1168 * Determines if the instance is a weekday
1169 *
1170 * @return boolean
1171 */
1172 public function isWeekday()
1173 {
1174 return ($this->dayOfWeek != self::SUNDAY && $this->dayOfWeek != self::SATURDAY);
1175 }
1176
1177 /**
1178 * Determines if the instance is a weekend day
1179 *
1180 * @return boolean
1181 */
1182 public function isWeekend()
1183 {
1184 return !$this->isWeekDay();
1185 }
1186
1187 /**
1188 * Determines if the instance is yesterday
1189 *
1190 * @return boolean
1191 */
1192 public function isYesterday()
1193 {
1194 return $this->toDateString() === static::yesterday($this->tz)->toDateString();
1195 }
1196
1197 /**
1198 * Determines if the instance is today
1199 *
1200 * @return boolean
1201 */
1202 public function isToday()
1203 {
1204 return $this->toDateString() === static::now($this->tz)->toDateString();
1205 }
1206
1207 /**
1208 * Determines if the instance is tomorrow
1209 *
1210 * @return boolean
1211 */
1212 public function isTomorrow()
1213 {
1214 return $this->toDateString() === static::tomorrow($this->tz)->toDateString();
1215 }
1216
1217 /**
1218 * Determines if the instance is in the future, ie. greater (after) than now
1219 *
1220 * @return boolean
1221 */
1222 public function isFuture()
1223 {
1224 return $this->gt(static::now($this->tz));
1225 }
1226
1227 /**
1228 * Determines if the instance is in the past, ie. less (before) than now
1229 *
1230 * @return boolean
1231 */
1232 public function isPast()
1233 {
1234 return $this->lt(static::now($this->tz));
1235 }
1236
1237 /**
1238 * Determines if the instance is a leap year
1239 *
1240 * @return boolean
1241 */
1242 public function isLeapYear()
1243 {
1244 return $this->format('L') == '1';
1245 }
1246
1247 /**
1248 * Checks if the passed in date is the same day as the instance current day.
1249 *
1250 * @param Carbon $dt
1251 * @return boolean
1252 */
1253 public function isSameDay(Carbon $dt)
1254 {
1255 return $this->toDateString() === $dt->toDateString();
1256 }
1257
1258 ///////////////////////////////////////////////////////////////////
1259 /////////////////// ADDITIONS AND SUBSTRACTIONS ///////////////////
1260 ///////////////////////////////////////////////////////////////////
1261
1262 /**
1263 * Add years to the instance. Positive $value travel forward while
1264 * negative $value travel into the past.
1265 *
1266 * @param integer $value
1267 *
1268 * @return static
1269 */
1270 public function addYears($value)
1271 {
1272 return $this->modify((int) $value . ' year');
1273 }
1274
1275 /**
1276 * Add a year to the instance
1277 *
1278 * @return static
1279 */
1280 public function addYear()
1281 {
1282 return $this->addYears(1);
1283 }
1284
1285 /**
1286 * Remove a year from the instance
1287 *
1288 * @return static
1289 */
1290 public function subYear()
1291 {
1292 return $this->addYears(-1);
1293 }
1294
1295 /**
1296 * Remove years from the instance.
1297 *
1298 * @param integer $value
1299 *
1300 * @return static
1301 */
1302 public function subYears($value)
1303 {
1304 return $this->addYears(-1 * $value);
1305 }
1306
1307 /**
1308 * Add months to the instance. Positive $value travels forward while
1309 * negative $value travels into the past.
1310 *
1311 * @param integer $value
1312 *
1313 * @return static
1314 */
1315 public function addMonths($value)
1316 {
1317 return $this->modify((int) $value . ' month');
1318 }
1319
1320 /**
1321 * Add a month to the instance
1322 *
1323 * @return static
1324 */
1325 public function addMonth()
1326 {
1327 return $this->addMonths(1);
1328 }
1329
1330 /**
1331 * Remove a month from the instance
1332 *
1333 * @return static
1334 */
1335 public function subMonth()
1336 {
1337 return $this->addMonths(-1);
1338 }
1339
1340 /**
1341 * Remove months from the instance
1342 *
1343 * @param integer $value
1344 *
1345 * @return static
1346 */
1347 public function subMonths($value)
1348 {
1349 return $this->addMonths(-1 * $value);
1350 }
1351
1352 /**
1353 * Add days to the instance. Positive $value travels forward while
1354 * negative $value travels into the past.
1355 *
1356 * @param integer $value
1357 *
1358 * @return static
1359 */
1360 public function addDays($value)
1361 {
1362 return $this->modify((int) $value . ' day');
1363 }
1364
1365 /**
1366 * Add a day to the instance
1367 *
1368 * @return static
1369 */
1370 public function addDay()
1371 {
1372 return $this->addDays(1);
1373 }
1374
1375 /**
1376 * Remove a day from the instance
1377 *
1378 * @return static
1379 */
1380 public function subDay()
1381 {
1382 return $this->addDays(-1);
1383 }
1384
1385 /**
1386 * Remove days from the instance
1387 *
1388 * @param integer $value
1389 *
1390 * @return static
1391 */
1392 public function subDays($value)
1393 {
1394 return $this->addDays(-1 * $value);
1395 }
1396
1397 /**
1398 * Add weekdays to the instance. Positive $value travels forward while
1399 * negative $value travels into the past.
1400 *
1401 * @param integer $value
1402 *
1403 * @return static
1404 */
1405 public function addWeekdays($value)
1406 {
1407 return $this->modify((int) $value . ' weekday');
1408 }
1409
1410 /**
1411 * Add a weekday to the instance
1412 *
1413 * @return static
1414 */
1415 public function addWeekday()
1416 {
1417 return $this->addWeekdays(1);
1418 }
1419
1420 /**
1421 * Remove a weekday from the instance
1422 *
1423 * @return static
1424 */
1425 public function subWeekday()
1426 {
1427 return $this->addWeekdays(-1);
1428 }
1429
1430 /**
1431 * Remove weekdays from the instance
1432 *
1433 * @param integer $value
1434 *
1435 * @return static
1436 */
1437 public function subWeekdays($value)
1438 {
1439 return $this->addWeekdays(-1 * $value);
1440 }
1441
1442 /**
1443 * Add weeks to the instance. Positive $value travels forward while
1444 * negative $value travels into the past.
1445 *
1446 * @param integer $value
1447 *
1448 * @return static
1449 */
1450 public function addWeeks($value)
1451 {
1452 return $this->modify((int) $value . ' week');
1453 }
1454
1455 /**
1456 * Add a week to the instance
1457 *
1458 * @return static
1459 */
1460 public function addWeek()
1461 {
1462 return $this->addWeeks(1);
1463 }
1464
1465 /**
1466 * Remove a week from the instance
1467 *
1468 * @return static
1469 */
1470 public function subWeek()
1471 {
1472 return $this->addWeeks(-1);
1473 }
1474
1475 /**
1476 * Remove weeks to the instance
1477 *
1478 * @param integer $value
1479 *
1480 * @return static
1481 */
1482 public function subWeeks($value)
1483 {
1484 return $this->addWeeks(-1 * $value);
1485 }
1486
1487 /**
1488 * Add hours to the instance. Positive $value travels forward while
1489 * negative $value travels into the past.
1490 *
1491 * @param integer $value
1492 *
1493 * @return static
1494 */
1495 public function addHours($value)
1496 {
1497 return $this->modify((int) $value . ' hour');
1498 }
1499
1500 /**
1501 * Add an hour to the instance
1502 *
1503 * @return static
1504 */
1505 public function addHour()
1506 {
1507 return $this->addHours(1);
1508 }
1509
1510 /**
1511 * Remove an hour from the instance
1512 *
1513 * @return static
1514 */
1515 public function subHour()
1516 {
1517 return $this->addHours(-1);
1518 }
1519
1520 /**
1521 * Remove hours from the instance
1522 *
1523 * @param integer $value
1524 *
1525 * @return static
1526 */
1527 public function subHours($value)
1528 {
1529 return $this->addHours(-1 * $value);
1530 }
1531
1532 /**
1533 * Add minutes to the instance. Positive $value travels forward while
1534 * negative $value travels into the past.
1535 *
1536 * @param integer $value
1537 *
1538 * @return static
1539 */
1540 public function addMinutes($value)
1541 {
1542 return $this->modify((int) $value . ' minute');
1543 }
1544
1545 /**
1546 * Add a minute to the instance
1547 *
1548 * @return static
1549 */
1550 public function addMinute()
1551 {
1552 return $this->addMinutes(1);
1553 }
1554
1555 /**
1556 * Remove a minute from the instance
1557 *
1558 * @return static
1559 */
1560 public function subMinute()
1561 {
1562 return $this->addMinutes(-1);
1563 }
1564
1565 /**
1566 * Remove minutes from the instance
1567 *
1568 * @param integer $value
1569 *
1570 * @return static
1571 */
1572 public function subMinutes($value)
1573 {
1574 return $this->addMinutes(-1 * $value);
1575 }
1576
1577 /**
1578 * Add seconds to the instance. Positive $value travels forward while
1579 * negative $value travels into the past.
1580 *
1581 * @param integer $value
1582 *
1583 * @return static
1584 */
1585 public function addSeconds($value)
1586 {
1587 return $this->modify((int) $value . ' second');
1588 }
1589
1590 /**
1591 * Add a second to the instance
1592 *
1593 * @return static
1594 */
1595 public function addSecond()
1596 {
1597 return $this->addSeconds(1);
1598 }
1599
1600 /**
1601 * Remove a second from the instance
1602 *
1603 * @return static
1604 */
1605 public function subSecond()
1606 {
1607 return $this->addSeconds(-1);
1608 }
1609
1610 /**
1611 * Remove seconds from the instance
1612 *
1613 * @param integer $value
1614 *
1615 * @return static
1616 */
1617 public function subSeconds($value)
1618 {
1619 return $this->addSeconds(-1 * $value);
1620 }
1621
1622 ///////////////////////////////////////////////////////////////////
1623 /////////////////////////// DIFFERENCES ///////////////////////////
1624 ///////////////////////////////////////////////////////////////////
1625
1626 /**
1627 * Get the difference in years
1628 *
1629 * @param Carbon $dt
1630 * @param boolean $abs Get the absolute of the difference
1631 *
1632 * @return integer
1633 */
1634 public function diffInYears(Carbon $dt = null, $abs = true)
1635 {
1636 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1637
1638 return (int) $this->diff($dt, $abs)->format('%r%y');
1639 }
1640
1641 /**
1642 * Get the difference in months
1643 *
1644 * @param Carbon $dt
1645 * @param boolean $abs Get the absolute of the difference
1646 *
1647 * @return integer
1648 */
1649 public function diffInMonths(Carbon $dt = null, $abs = true)
1650 {
1651 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1652
1653 return $this->diffInYears($dt, $abs) * self::MONTHS_PER_YEAR + $this->diff($dt, $abs)->format('%r%m');
1654 }
1655
1656 /**
1657 * Get the difference in weeks
1658 *
1659 * @param Carbon $dt
1660 * @param boolean $abs Get the absolute of the difference
1661 *
1662 * @return integer
1663 */
1664 public function diffInWeeks(Carbon $dt = null, $abs = true)
1665 {
1666 return (int) ($this->diffInDays($dt, $abs) / self::DAYS_PER_WEEK);
1667 }
1668
1669 /**
1670 * Get the difference in days
1671 *
1672 * @param Carbon $dt
1673 * @param boolean $abs Get the absolute of the difference
1674 *
1675 * @return integer
1676 */
1677 public function diffInDays(Carbon $dt = null, $abs = true)
1678 {
1679 $dt = ($dt === null) ? static::now($this->tz) : $dt;
1680
1681 return (int) $this->diff($dt, $abs)->format('%r%a');
1682 }
1683
1684 /**
1685 * Get the difference in days using a filter closure
1686 *
1687 * @param Closure $callback
1688 * @param Carbon $dt
1689 * @param boolean $abs Get the absolute of the difference
1690 *
1691 * @return int
1692 */
1693 public function diffInDaysFiltered(Closure $callback, Carbon $dt = null, $abs = true)
1694 {
1695 $start = $this;
1696 $end = ($dt === null) ? static::now($this->tz) : $dt;
1697 $inverse = false;
1698
1699 if ($end < $start) {
1700 $start = $end;
1701 $end = $this;
1702 $inverse = true;
1703 }
1704
1705 $period = new DatePeriod($start, new DateInterval('P1D'), $end);
1706 $days = array_filter(iterator_to_array($period), function (DateTime $date) use ($callback) {
1707 return call_user_func($callback, Carbon::instance($date));
1708 });
1709
1710 $diff = count($days);
1711
1712 return $inverse && !$abs ? -$diff : $diff;
1713 }
1714
1715 /**
1716 * Get the difference in weekdays
1717 *
1718 * @param Carbon $dt
1719 * @param boolean $abs Get the absolute of the difference
1720 *
1721 * @return int
1722 */
1723 public function diffInWeekdays(Carbon $dt = null, $abs = true)
1724 {
1725 return $this->diffInDaysFiltered(function (Carbon $date) {
1726 return $date->isWeekday();
1727 }, $dt, $abs);
1728 }
1729
1730 /**
1731 * Get the difference in weekend days using a filter
1732 *
1733 * @param Carbon $dt
1734 * @param boolean $abs Get the absolute of the difference
1735 *
1736 * @return int
1737 */
1738 public function diffInWeekendDays(Carbon $dt = null, $abs = true)
1739 {
1740 return $this->diffInDaysFiltered(function (Carbon $date) {
1741 return $date->isWeekend();
1742 }, $dt, $abs);
1743 }
1744
1745 /**
1746 * Get the difference in hours
1747 *
1748 * @param Carbon $dt
1749 * @param boolean $abs Get the absolute of the difference
1750 *
1751 * @return integer
1752 */
1753 public function diffInHours(Carbon $dt = null, $abs = true)
1754 {
1755 return (int) ($this->diffInSeconds($dt, $abs) / self::SECONDS_PER_MINUTE / self::MINUTES_PER_HOUR);
1756 }
1757
1758 /**
1759 * Get the difference in minutes
1760 *
1761 * @param Carbon $dt
1762 * @param boolean $abs Get the absolute of the difference
1763 *
1764 * @return integer
1765 */
1766 public function diffInMinutes(Carbon $dt = null, $abs = true)
1767 {
1768 return (int) ($this->diffInSeconds($dt, $abs) / self::SECONDS_PER_MINUTE);
1769 }
1770
1771 /**
1772 * Get the difference in seconds
1773 *
1774 * @param Carbon $dt
1775 * @param boolean $abs Get the absolute of the difference
1776 *
1777 * @return integer
1778 */
1779 public function diffInSeconds(Carbon $dt = null, $abs = true)
1780 {
1781 $value = (($dt === null) ? time() : $dt->getTimestamp()) - $this->getTimestamp();
1782
1783 return $abs ? abs($value) : $value;
1784 }
1785
1786 /**
1787 * Get the difference in a human readable format.
1788 *
1789 * When comparing a value in the past to default now:
1790 * 1 hour ago
1791 * 5 months ago
1792 *
1793 * When comparing a value in the future to default now:
1794 * 1 hour from now
1795 * 5 months from now
1796 *
1797 * When comparing a value in the past to another value:
1798 * 1 hour before
1799 * 5 months before
1800 *
1801 * When comparing a value in the future to another value:
1802 * 1 hour after
1803 * 5 months after
1804 *
1805 * @param Carbon $other
1806 *
1807 * @return string
1808 */
1809 public function diffForHumans(Carbon $other = null)
1810 {
1811 $isNow = $other === null;
1812
1813 if ($isNow) {
1814 $other = static::now($this->tz);
1815 }
1816
1817 $isFuture = $this->gt($other);
1818
1819 $delta = $other->diffInSeconds($this);
1820
1821 // a little weeks per month, 365 days per year... good enough!!
1822 $divs = array(
1823 'second' => self::SECONDS_PER_MINUTE,
1824 'minute' => self::MINUTES_PER_HOUR,
1825 'hour' => self::HOURS_PER_DAY,
1826 'day' => self::DAYS_PER_WEEK,
1827 'week' => 30 / self::DAYS_PER_WEEK,
1828 'month' => self::MONTHS_PER_YEAR
1829 );
1830
1831 $unit = 'year';
1832
1833 foreach ($divs as $divUnit => $divValue) {
1834 if ($delta < $divValue) {
1835 $unit = $divUnit;
1836 break;
1837 }
1838
1839 $delta = $delta / $divValue;
1840 }
1841
1842 $delta = (int) $delta;
1843
1844 if ($delta == 0) {
1845 $delta = 1;
1846 }
1847
1848 $txt = $delta . ' ' . $unit;
1849 $txt .= $delta == 1 ? '' : 's';
1850
1851 if ($isNow) {
1852 if ($isFuture) {
1853 return $txt . ' from now';
1854 }
1855
1856 return $txt . ' ago';
1857 }
1858
1859 if ($isFuture) {
1860 return $txt . ' after';
1861 }
1862
1863 return $txt . ' before';
1864 }
1865
1866 ///////////////////////////////////////////////////////////////////
1867 //////////////////////////// MODIFIERS ////////////////////////////
1868 ///////////////////////////////////////////////////////////////////
1869
1870 /**
1871 * Resets the time to 00:00:00
1872 *
1873 * @return static
1874 */
1875 public function startOfDay()
1876 {
1877 return $this->hour(0)->minute(0)->second(0);
1878 }
1879
1880 /**
1881 * Resets the time to 23:59:59
1882 *
1883 * @return static
1884 */
1885 public function endOfDay()
1886 {
1887 return $this->hour(23)->minute(59)->second(59);
1888 }
1889
1890 /**
1891 * Resets the date to the first day of the month and the time to 00:00:00
1892 *
1893 * @return static
1894 */
1895 public function startOfMonth()
1896 {
1897 return $this->startOfDay()->day(1);
1898 }
1899
1900 /**
1901 * Resets the date to end of the month and time to 23:59:59
1902 *
1903 * @return static
1904 */
1905 public function endOfMonth()
1906 {
1907 return $this->day($this->daysInMonth)->endOfDay();
1908 }
1909
1910 /**
1911 * Resets the date to the first day of the year and the time to 00:00:00
1912 *
1913 * @return static
1914 */
1915 public function startOfYear()
1916 {
1917 return $this->month(1)->startOfMonth();
1918 }
1919
1920 /**
1921 * Resets the date to end of the year and time to 23:59:59
1922 *
1923 * @return static
1924 */
1925 public function endOfYear()
1926 {
1927 return $this->month(self::MONTHS_PER_YEAR)->endOfMonth();
1928 }
1929
1930 /**
1931 * Resets the date to the first day of the decade and the time to 00:00:00
1932 *
1933 * @return static
1934 */
1935 public function startOfDecade()
1936 {
1937 return $this->startOfYear()->year($this->year - $this->year % self::YEARS_PER_DECADE);
1938 }
1939
1940 /**
1941 * Resets the date to end of the decade and time to 23:59:59
1942 *
1943 * @return static
1944 */
1945 public function endOfDecade()
1946 {
1947 return $this->endOfYear()->year($this->year - $this->year % self::YEARS_PER_DECADE + self::YEARS_PER_DECADE - 1);
1948 }
1949
1950 /**
1951 * Resets the date to the first day of the century and the time to 00:00:00
1952 *
1953 * @return static
1954 */
1955 public function startOfCentury()
1956 {
1957 return $this->startOfYear()->year($this->year - $this->year % self::YEARS_PER_CENTURY);
1958 }
1959
1960 /**
1961 * Resets the date to end of the century and time to 23:59:59
1962 *
1963 * @return static
1964 */
1965 public function endOfCentury()
1966 {
1967 return $this->endOfYear()->year($this->year - $this->year % self::YEARS_PER_CENTURY + self::YEARS_PER_CENTURY - 1);
1968 }
1969
1970 /**
1971 * Resets the date to the first day of the ISO-8601 week (Monday) and the time to 00:00:00
1972 *
1973 * @return static
1974 */
1975 public function startOfWeek()
1976 {
1977 if ($this->dayOfWeek != self::MONDAY) $this->previous(self::MONDAY);
1978 return $this->startOfDay();
1979 }
1980
1981 /**
1982 * Resets the date to end of the ISO-8601 week (Sunday) and time to 23:59:59
1983 *
1984 * @return static
1985 */
1986 public function endOfWeek()
1987 {
1988 if ($this->dayOfWeek != self::SUNDAY) $this->next(self::SUNDAY);
1989 return $this->endOfDay();
1990 }
1991
1992 /**
1993 * Modify to the next occurance of a given day of the week.
1994 * If no dayOfWeek is provided, modify to the next occurance
1995 * of the current day of the week. Use the supplied consts
1996 * to indicate the desired dayOfWeek, ex. static::MONDAY.
1997 *
1998 * @param int $dayOfWeek
1999 *
2000 * @return mixed
2001 */
2002 public function next($dayOfWeek = null)
2003 {
2004 if ($dayOfWeek === null) {
2005 $dayOfWeek = $this->dayOfWeek;
2006 }
2007
2008 return $this->startOfDay()->modify('next ' . self::$days[$dayOfWeek]);
2009 }
2010
2011 /**
2012 * Modify to the previous occurance of a given day of the week.
2013 * If no dayOfWeek is provided, modify to the previous occurance
2014 * of the current day of the week. Use the supplied consts
2015 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2016 *
2017 * @param int $dayOfWeek
2018 *
2019 * @return mixed
2020 */
2021 public function previous($dayOfWeek = null)
2022 {
2023 if ($dayOfWeek === null) {
2024 $dayOfWeek = $this->dayOfWeek;
2025 }
2026
2027 return $this->startOfDay()->modify('last ' . self::$days[$dayOfWeek]);
2028 }
2029
2030 /**
2031 * Modify to the first occurance of a given day of the week
2032 * in the current month. If no dayOfWeek is provided, modify to the
2033 * first day of the current month. Use the supplied consts
2034 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2035 *
2036 * @param int $dayOfWeek
2037 *
2038 * @return mixed
2039 */
2040 public function firstOfMonth($dayOfWeek = null)
2041 {
2042 $this->startOfDay();
2043
2044 if ($dayOfWeek === null) {
2045 return $this->day(1);
2046 }
2047
2048 return $this->modify('first ' . self::$days[$dayOfWeek] . ' of ' . $this->format('F') . ' ' . $this->year);
2049 }
2050
2051 /**
2052 * Modify to the last occurance of a given day of the week
2053 * in the current month. If no dayOfWeek is provided, modify to the
2054 * last day of the current month. Use the supplied consts
2055 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2056 *
2057 * @param int $dayOfWeek
2058 *
2059 * @return mixed
2060 */
2061 public function lastOfMonth($dayOfWeek = null)
2062 {
2063 $this->startOfDay();
2064
2065 if ($dayOfWeek === null) {
2066 return $this->day($this->daysInMonth);
2067 }
2068
2069 return $this->modify('last ' . self::$days[$dayOfWeek] . ' of ' . $this->format('F') . ' ' . $this->year);
2070 }
2071
2072 /**
2073 * Modify to the given occurance of a given day of the week
2074 * in the current month. If the calculated occurance is outside the scope
2075 * of the current month, then return false and no modifications are made.
2076 * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY.
2077 *
2078 * @param int $nth
2079 * @param int $dayOfWeek
2080 *
2081 * @return mixed
2082 */
2083 public function nthOfMonth($nth, $dayOfWeek)
2084 {
2085 $dt = $this->copy()->firstOfMonth();
2086 $check = $dt->format('Y-m');
2087 $dt->modify('+' . $nth . ' ' . self::$days[$dayOfWeek]);
2088
2089 return ($dt->format('Y-m') === $check) ? $this->modify($dt) : false;
2090 }
2091
2092 /**
2093 * Modify to the first occurance of a given day of the week
2094 * in the current quarter. If no dayOfWeek is provided, modify to the
2095 * first day of the current quarter. Use the supplied consts
2096 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2097 *
2098 * @param int $dayOfWeek
2099 *
2100 * @return mixed
2101 */
2102 public function firstOfQuarter($dayOfWeek = null)
2103 {
2104 return $this->day(1)->month($this->quarter * 3 - 2)->firstOfMonth($dayOfWeek);
2105 }
2106
2107 /**
2108 * Modify to the last occurance of a given day of the week
2109 * in the current quarter. If no dayOfWeek is provided, modify to the
2110 * last day of the current quarter. Use the supplied consts
2111 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2112 *
2113 * @param int $dayOfWeek
2114 *
2115 * @return mixed
2116 */
2117 public function lastOfQuarter($dayOfWeek = null)
2118 {
2119 return $this->day(1)->month($this->quarter * 3)->lastOfMonth($dayOfWeek);
2120 }
2121
2122 /**
2123 * Modify to the given occurance of a given day of the week
2124 * in the current quarter. If the calculated occurance is outside the scope
2125 * of the current quarter, then return false and no modifications are made.
2126 * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY.
2127 *
2128 * @param int $nth
2129 * @param int $dayOfWeek
2130 *
2131 * @return mixed
2132 */
2133 public function nthOfQuarter($nth, $dayOfWeek)
2134 {
2135 $dt = $this->copy()->day(1)->month($this->quarter * 3);
2136 $last_month = $dt->month;
2137 $year = $dt->year;
2138 $dt->firstOfQuarter()->modify('+' . $nth . ' ' . self::$days[$dayOfWeek]);
2139
2140 return ($last_month < $dt->month || $year !== $dt->year) ? false : $this->modify($dt);
2141 }
2142
2143 /**
2144 * Modify to the first occurance of a given day of the week
2145 * in the current year. If no dayOfWeek is provided, modify to the
2146 * first day of the current year. Use the supplied consts
2147 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2148 *
2149 * @param int $dayOfWeek
2150 *
2151 * @return mixed
2152 */
2153 public function firstOfYear($dayOfWeek = null)
2154 {
2155 return $this->month(1)->firstOfMonth($dayOfWeek);
2156 }
2157
2158 /**
2159 * Modify to the last occurance of a given day of the week
2160 * in the current year. If no dayOfWeek is provided, modify to the
2161 * last day of the current year. Use the supplied consts
2162 * to indicate the desired dayOfWeek, ex. static::MONDAY.
2163 *
2164 * @param int $dayOfWeek
2165 *
2166 * @return mixed
2167 */
2168 public function lastOfYear($dayOfWeek = null)
2169 {
2170 return $this->month(self::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek);
2171 }
2172
2173 /**
2174 * Modify to the given occurance of a given day of the week
2175 * in the current year. If the calculated occurance is outside the scope
2176 * of the current year, then return false and no modifications are made.
2177 * Use the supplied consts to indicate the desired dayOfWeek, ex. static::MONDAY.
2178 *
2179 * @param int $nth
2180 * @param int $dayOfWeek
2181 *
2182 * @return mixed
2183 */
2184 public function nthOfYear($nth, $dayOfWeek)
2185 {
2186 $dt = $this->copy()->firstOfYear()->modify('+' . $nth . ' ' . self::$days[$dayOfWeek]);
2187
2188 return $this->year == $dt->year ? $this->modify($dt) : false;
2189 }
2190
2191 /**
2192 * Modify the current instance to the average of a given instance (default now) and the current instance.
2193 *
2194 * @param Carbon $dt
2195 *
2196 * @return static
2197 */
2198 public function average(Carbon $dt = null)
2199 {
2200 $dt = ($dt === null) ? static::now($this->tz) : $dt;
2201
2202 return $this->addSeconds((int) ($this->diffInSeconds($dt, false) / 2));
2203 }
2204
2205 /**
2206 * Check if its the birthday. Compares the date/month values of the two dates.
2207 * @param Carbon $dt
2208 * @return boolean
2209 */
2210 public function isBirthday(Carbon $dt)
2211 {
2212 return $this->month === $dt->month && $this->day === $dt->day;
2213 }
2214 }
2215