vendor/nesbot/carbon/src/Carbon/Traits/Modifiers.php line 437

Open in your IDE?
  1. <?php
  2. /**
  3.  * This file is part of the Carbon package.
  4.  *
  5.  * (c) Brian Nesbitt <brian@nesbot.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Carbon\Traits;
  11. use Carbon\CarbonInterface;
  12. use ReturnTypeWillChange;
  13. /**
  14.  * Trait Modifiers.
  15.  *
  16.  * Returns dates relative to current date using modifier short-hand.
  17.  */
  18. trait Modifiers
  19. {
  20.     /**
  21.      * Midday/noon hour.
  22.      *
  23.      * @var int
  24.      */
  25.     protected static $midDayAt 12;
  26.     /**
  27.      * get midday/noon hour
  28.      *
  29.      * @return int
  30.      */
  31.     public static function getMidDayAt()
  32.     {
  33.         return static::$midDayAt;
  34.     }
  35.     /**
  36.      * @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
  37.      *             You should rather consider mid-day is always 12pm, then if you need to test if it's an other
  38.      *             hour, test it explicitly:
  39.      *                 $date->format('G') == 13
  40.      *             or to set explicitly to a given hour:
  41.      *                 $date->setTime(13, 0, 0, 0)
  42.      *
  43.      * Set midday/noon hour
  44.      *
  45.      * @param int $hour midday hour
  46.      *
  47.      * @return void
  48.      */
  49.     public static function setMidDayAt($hour)
  50.     {
  51.         static::$midDayAt $hour;
  52.     }
  53.     /**
  54.      * Modify to midday, default to self::$midDayAt
  55.      *
  56.      * @return static
  57.      */
  58.     public function midDay()
  59.     {
  60.         return $this->setTime(static::$midDayAt000);
  61.     }
  62.     /**
  63.      * Modify to the next occurrence of a given modifier such as a day of
  64.      * the week. If no modifier is provided, modify to the next occurrence
  65.      * of the current day of the week. Use the supplied constants
  66.      * to indicate the desired dayOfWeek, ex. static::MONDAY.
  67.      *
  68.      * @param string|int|null $modifier
  69.      *
  70.      * @return static|false
  71.      */
  72.     public function next($modifier null)
  73.     {
  74.         if ($modifier === null) {
  75.             $modifier $this->dayOfWeek;
  76.         }
  77.         return $this->change(
  78.             'next '.(\is_string($modifier) ? $modifier : static::$days[$modifier])
  79.         );
  80.     }
  81.     /**
  82.      * Go forward or backward to the next week- or weekend-day.
  83.      *
  84.      * @param bool $weekday
  85.      * @param bool $forward
  86.      *
  87.      * @return static
  88.      */
  89.     private function nextOrPreviousDay($weekday true$forward true)
  90.     {
  91.         /** @var CarbonInterface $date */
  92.         $date $this;
  93.         $step $forward : -1;
  94.         do {
  95.             $date $date->addDays($step);
  96.         } while ($weekday $date->isWeekend() : $date->isWeekday());
  97.         return $date;
  98.     }
  99.     /**
  100.      * Go forward to the next weekday.
  101.      *
  102.      * @return static
  103.      */
  104.     public function nextWeekday()
  105.     {
  106.         return $this->nextOrPreviousDay();
  107.     }
  108.     /**
  109.      * Go backward to the previous weekday.
  110.      *
  111.      * @return static
  112.      */
  113.     public function previousWeekday()
  114.     {
  115.         return $this->nextOrPreviousDay(truefalse);
  116.     }
  117.     /**
  118.      * Go forward to the next weekend day.
  119.      *
  120.      * @return static
  121.      */
  122.     public function nextWeekendDay()
  123.     {
  124.         return $this->nextOrPreviousDay(false);
  125.     }
  126.     /**
  127.      * Go backward to the previous weekend day.
  128.      *
  129.      * @return static
  130.      */
  131.     public function previousWeekendDay()
  132.     {
  133.         return $this->nextOrPreviousDay(falsefalse);
  134.     }
  135.     /**
  136.      * Modify to the previous occurrence of a given modifier such as a day of
  137.      * the week. If no dayOfWeek is provided, modify to the previous occurrence
  138.      * of the current day of the week. Use the supplied constants
  139.      * to indicate the desired dayOfWeek, ex. static::MONDAY.
  140.      *
  141.      * @param string|int|null $modifier
  142.      *
  143.      * @return static|false
  144.      */
  145.     public function previous($modifier null)
  146.     {
  147.         if ($modifier === null) {
  148.             $modifier $this->dayOfWeek;
  149.         }
  150.         return $this->change(
  151.             'last '.(\is_string($modifier) ? $modifier : static::$days[$modifier])
  152.         );
  153.     }
  154.     /**
  155.      * Modify to the first occurrence of a given day of the week
  156.      * in the current month. If no dayOfWeek is provided, modify to the
  157.      * first day of the current month.  Use the supplied constants
  158.      * to indicate the desired dayOfWeek, ex. static::MONDAY.
  159.      *
  160.      * @param int|null $dayOfWeek
  161.      *
  162.      * @return static
  163.      */
  164.     public function firstOfMonth($dayOfWeek null)
  165.     {
  166.         $date $this->startOfDay();
  167.         if ($dayOfWeek === null) {
  168.             return $date->day(1);
  169.         }
  170.         return $date->modify('first '.static::$days[$dayOfWeek].' of '.$date->rawFormat('F').' '.$date->year);
  171.     }
  172.     /**
  173.      * Modify to the last occurrence of a given day of the week
  174.      * in the current month. If no dayOfWeek is provided, modify to the
  175.      * last day of the current month.  Use the supplied constants
  176.      * to indicate the desired dayOfWeek, ex. static::MONDAY.
  177.      *
  178.      * @param int|null $dayOfWeek
  179.      *
  180.      * @return static
  181.      */
  182.     public function lastOfMonth($dayOfWeek null)
  183.     {
  184.         $date $this->startOfDay();
  185.         if ($dayOfWeek === null) {
  186.             return $date->day($date->daysInMonth);
  187.         }
  188.         return $date->modify('last '.static::$days[$dayOfWeek].' of '.$date->rawFormat('F').' '.$date->year);
  189.     }
  190.     /**
  191.      * Modify to the given occurrence of a given day of the week
  192.      * in the current month. If the calculated occurrence is outside the scope
  193.      * of the current month, then return false and no modifications are made.
  194.      * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
  195.      *
  196.      * @param int $nth
  197.      * @param int $dayOfWeek
  198.      *
  199.      * @return mixed
  200.      */
  201.     public function nthOfMonth($nth$dayOfWeek)
  202.     {
  203.         $date $this->avoidMutation()->firstOfMonth();
  204.         $check $date->rawFormat('Y-m');
  205.         $date $date->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
  206.         return $date->rawFormat('Y-m') === $check $this->modify((string) $date) : false;
  207.     }
  208.     /**
  209.      * Modify to the first occurrence of a given day of the week
  210.      * in the current quarter. If no dayOfWeek is provided, modify to the
  211.      * first day of the current quarter.  Use the supplied constants
  212.      * to indicate the desired dayOfWeek, ex. static::MONDAY.
  213.      *
  214.      * @param int|null $dayOfWeek day of the week default null
  215.      *
  216.      * @return static
  217.      */
  218.     public function firstOfQuarter($dayOfWeek null)
  219.     {
  220.         return $this->setDate($this->year$this->quarter * static::MONTHS_PER_QUARTER 21)->firstOfMonth($dayOfWeek);
  221.     }
  222.     /**
  223.      * Modify to the last occurrence of a given day of the week
  224.      * in the current quarter. If no dayOfWeek is provided, modify to the
  225.      * last day of the current quarter.  Use the supplied constants
  226.      * to indicate the desired dayOfWeek, ex. static::MONDAY.
  227.      *
  228.      * @param int|null $dayOfWeek day of the week default null
  229.      *
  230.      * @return static
  231.      */
  232.     public function lastOfQuarter($dayOfWeek null)
  233.     {
  234.         return $this->setDate($this->year$this->quarter * static::MONTHS_PER_QUARTER1)->lastOfMonth($dayOfWeek);
  235.     }
  236.     /**
  237.      * Modify to the given occurrence of a given day of the week
  238.      * in the current quarter. If the calculated occurrence is outside the scope
  239.      * of the current quarter, then return false and no modifications are made.
  240.      * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
  241.      *
  242.      * @param int $nth
  243.      * @param int $dayOfWeek
  244.      *
  245.      * @return mixed
  246.      */
  247.     public function nthOfQuarter($nth$dayOfWeek)
  248.     {
  249.         $date $this->avoidMutation()->day(1)->month($this->quarter * static::MONTHS_PER_QUARTER);
  250.         $lastMonth $date->month;
  251.         $year $date->year;
  252.         $date $date->firstOfQuarter()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
  253.         return ($lastMonth $date->month || $year !== $date->year) ? false $this->modify((string) $date);
  254.     }
  255.     /**
  256.      * Modify to the first occurrence of a given day of the week
  257.      * in the current year. If no dayOfWeek is provided, modify to the
  258.      * first day of the current year.  Use the supplied constants
  259.      * to indicate the desired dayOfWeek, ex. static::MONDAY.
  260.      *
  261.      * @param int|null $dayOfWeek day of the week default null
  262.      *
  263.      * @return static
  264.      */
  265.     public function firstOfYear($dayOfWeek null)
  266.     {
  267.         return $this->month(1)->firstOfMonth($dayOfWeek);
  268.     }
  269.     /**
  270.      * Modify to the last occurrence of a given day of the week
  271.      * in the current year. If no dayOfWeek is provided, modify to the
  272.      * last day of the current year.  Use the supplied constants
  273.      * to indicate the desired dayOfWeek, ex. static::MONDAY.
  274.      *
  275.      * @param int|null $dayOfWeek day of the week default null
  276.      *
  277.      * @return static
  278.      */
  279.     public function lastOfYear($dayOfWeek null)
  280.     {
  281.         return $this->month(static::MONTHS_PER_YEAR)->lastOfMonth($dayOfWeek);
  282.     }
  283.     /**
  284.      * Modify to the given occurrence of a given day of the week
  285.      * in the current year. If the calculated occurrence is outside the scope
  286.      * of the current year, then return false and no modifications are made.
  287.      * Use the supplied constants to indicate the desired dayOfWeek, ex. static::MONDAY.
  288.      *
  289.      * @param int $nth
  290.      * @param int $dayOfWeek
  291.      *
  292.      * @return mixed
  293.      */
  294.     public function nthOfYear($nth$dayOfWeek)
  295.     {
  296.         $date $this->avoidMutation()->firstOfYear()->modify('+'.$nth.' '.static::$days[$dayOfWeek]);
  297.         return $this->year === $date->year $this->modify((string) $date) : false;
  298.     }
  299.     /**
  300.      * Modify the current instance to the average of a given instance (default now) and the current instance
  301.      * (second-precision).
  302.      *
  303.      * @param \Carbon\Carbon|\DateTimeInterface|null $date
  304.      *
  305.      * @return static
  306.      */
  307.     public function average($date null)
  308.     {
  309.         return $this->addRealMicroseconds((int) ($this->diffInRealMicroseconds($this->resolveCarbon($date), false) / 2));
  310.     }
  311.     /**
  312.      * Get the closest date from the instance (second-precision).
  313.      *
  314.      * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
  315.      * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
  316.      *
  317.      * @return static
  318.      */
  319.     public function closest($date1$date2)
  320.     {
  321.         return $this->diffInRealMicroseconds($date1) < $this->diffInRealMicroseconds($date2) ? $date1 $date2;
  322.     }
  323.     /**
  324.      * Get the farthest date from the instance (second-precision).
  325.      *
  326.      * @param \Carbon\Carbon|\DateTimeInterface|mixed $date1
  327.      * @param \Carbon\Carbon|\DateTimeInterface|mixed $date2
  328.      *
  329.      * @return static
  330.      */
  331.     public function farthest($date1$date2)
  332.     {
  333.         return $this->diffInRealMicroseconds($date1) > $this->diffInRealMicroseconds($date2) ? $date1 $date2;
  334.     }
  335.     /**
  336.      * Get the minimum instance between a given instance (default now) and the current instance.
  337.      *
  338.      * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
  339.      *
  340.      * @return static
  341.      */
  342.     public function min($date null)
  343.     {
  344.         $date $this->resolveCarbon($date);
  345.         return $this->lt($date) ? $this $date;
  346.     }
  347.     /**
  348.      * Get the minimum instance between a given instance (default now) and the current instance.
  349.      *
  350.      * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
  351.      *
  352.      * @see min()
  353.      *
  354.      * @return static
  355.      */
  356.     public function minimum($date null)
  357.     {
  358.         return $this->min($date);
  359.     }
  360.     /**
  361.      * Get the maximum instance between a given instance (default now) and the current instance.
  362.      *
  363.      * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
  364.      *
  365.      * @return static
  366.      */
  367.     public function max($date null)
  368.     {
  369.         $date $this->resolveCarbon($date);
  370.         return $this->gt($date) ? $this $date;
  371.     }
  372.     /**
  373.      * Get the maximum instance between a given instance (default now) and the current instance.
  374.      *
  375.      * @param \Carbon\Carbon|\DateTimeInterface|mixed $date
  376.      *
  377.      * @see max()
  378.      *
  379.      * @return static
  380.      */
  381.     public function maximum($date null)
  382.     {
  383.         return $this->max($date);
  384.     }
  385.     /**
  386.      * Calls \DateTime::modify if mutable or \DateTimeImmutable::modify else.
  387.      *
  388.      * @see https://php.net/manual/en/datetime.modify.php
  389.      *
  390.      * @return static|false
  391.      */
  392.     #[ReturnTypeWillChange]
  393.     public function modify($modify)
  394.     {
  395.         return parent::modify((string) $modify);
  396.     }
  397.     /**
  398.      * Similar to native modify() method of DateTime but can handle more grammars.
  399.      *
  400.      * @example
  401.      * ```
  402.      * echo Carbon::now()->change('next 2pm');
  403.      * ```
  404.      *
  405.      * @link https://php.net/manual/en/datetime.modify.php
  406.      *
  407.      * @param string $modifier
  408.      *
  409.      * @return static|false
  410.      */
  411.     public function change($modifier)
  412.     {
  413.         return $this->modify(preg_replace_callback('/^(next|previous|last)\s+(\d{1,2}(h|am|pm|:\d{1,2}(:\d{1,2})?))$/i', function ($match) {
  414.             $match[2] = str_replace('h'':00'$match[2]);
  415.             $test $this->avoidMutation()->modify($match[2]);
  416.             $method $match[1] === 'next' 'lt' 'gt';
  417.             $match[1] = $test->$method($this) ? $match[1].' day' 'today';
  418.             return $match[1].' '.$match[2];
  419.         }, strtr(trim($modifier), [
  420.             ' at ' => ' ',
  421.             'just now' => 'now',
  422.             'after tomorrow' => 'tomorrow +1 day',
  423.             'before yesterday' => 'yesterday -1 day',
  424.         ])));
  425.     }
  426. }