A simple php website which displays quotes on pictures of pandas.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3165 lines
76 KiB

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