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

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