AddTest.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of the Carbon package.
  5. *
  6. * (c) Brian Nesbitt <brian@nesbot.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Tests\CarbonInterval;
  12. use Carbon\Carbon;
  13. use Carbon\CarbonInterval;
  14. use DateInterval;
  15. use DateTime;
  16. use DateTimeImmutable;
  17. use Generator;
  18. use InvalidArgumentException;
  19. use Tests\AbstractTestCase;
  20. class AddTest extends AbstractTestCase
  21. {
  22. public function testAdd()
  23. {
  24. $ci = CarbonInterval::create(4, 3, 6, 7, 8, 10, 11)->add(new DateInterval('P2Y1M5DT22H33M44S'));
  25. $this->assertCarbonInterval($ci, 6, 4, 54, 30, 43, 55);
  26. }
  27. /**
  28. * @requires PHP >= 8.0
  29. */
  30. public function testNamedParameters()
  31. {
  32. $ci = eval("return \Carbon\CarbonInterval::years(years: 3)->addYears(years: 4);");
  33. $this->assertCarbonInterval($ci, 7);
  34. $ci = eval("return \Carbon\CarbonInterval::months(months: 3)->addMonths(months: 4);");
  35. $this->assertCarbonInterval($ci, 0, 7);
  36. $ci = eval("return \Carbon\CarbonInterval::weeks(weeks: 3)->addWeeks(weeks: 4);");
  37. $this->assertCarbonInterval($ci, 0, 0, 7 * 7);
  38. $ci = eval("return \Carbon\CarbonInterval::days(days: 3)->addDays(days: 4);");
  39. $this->assertCarbonInterval($ci, 0, 0, 7);
  40. $ci = eval("return \Carbon\CarbonInterval::hours(hours: 3)->addHours(hours: 4);");
  41. $this->assertCarbonInterval($ci, 0, 0, 0, 7);
  42. $ci = eval("return \Carbon\CarbonInterval::minutes(minutes: 3)->addMinutes(minutes: 4);");
  43. $this->assertCarbonInterval($ci, 0, 0, 0, 0, 7);
  44. $ci = eval("return \Carbon\CarbonInterval::seconds(seconds: 3)->addSeconds(seconds: 4);");
  45. $this->assertCarbonInterval($ci, 0, 0, 0, 0, 0, 7);
  46. $ci = eval("return \Carbon\CarbonInterval::milliseconds(milliseconds: 3)->addMilliseconds(milliseconds: 4);");
  47. $this->assertCarbonInterval($ci, 0, 0, 0, 0, 0, 0, 7000);
  48. $ci = eval("return \Carbon\CarbonInterval::microseconds(microseconds: 3)->addMicroseconds(microseconds: 4);");
  49. $this->assertCarbonInterval($ci, 0, 0, 0, 0, 0, 0, 7);
  50. }
  51. public function testAddWithDiffDateInterval()
  52. {
  53. $diff = Carbon::now()->diff(Carbon::now()->addWeeks(3));
  54. $ci = CarbonInterval::create(4, 3, 6, 7, 8, 10, 11)->add($diff);
  55. $this->assertCarbonInterval($ci, 4, 3, 70, 8, 10, 11);
  56. }
  57. public function testAddWithNegativeDiffDateInterval()
  58. {
  59. $diff = Carbon::now()->diff(Carbon::now()->subWeeks(3));
  60. $ci = CarbonInterval::create(4, 3, 6, 7, 8, 10, 11)->add($diff);
  61. $this->assertCarbonInterval($ci, 4, 3, 28, 8, 10, 11);
  62. }
  63. public function testAddMicroseconds()
  64. {
  65. $diff = Carbon::now()->diff(Carbon::now()->addDays(3)->addMicroseconds(111222));
  66. $ci = CarbonInterval::create(1, 0, 0, 2, 0, 0, 0, 222333)->add($diff);
  67. if ($ci->seconds === 1) {
  68. $ci->seconds--;
  69. $ci->microseconds += 1000000;
  70. }
  71. $this->assertCarbonInterval($ci, 1, 0, 5, 0, 0, 0, 333555);
  72. $diff = Carbon::now()->diff(Carbon::now()->addDays(3));
  73. $ci = CarbonInterval::create(1, 0, 0, 2, 0, 0, 0, 222333)->add($diff);
  74. $this->assertCarbonInterval($ci, 1, 0, 5, 0, 0, 0, 222333);
  75. $diff = Carbon::now()->diff(Carbon::now()->addDays(3)->addMicroseconds(111222));
  76. $ci = CarbonInterval::create(1, 0, 0, 2, 0, 0, 0)->add($diff);
  77. if ($ci->seconds === 1) {
  78. $ci->seconds--;
  79. $ci->microseconds += 1000000;
  80. }
  81. $this->assertCarbonInterval($ci, 1, 0, 5, 0, 0, 0, 111222);
  82. }
  83. public function testAddWithRawDiffDateInterval()
  84. {
  85. date_default_timezone_set('UTC');
  86. $date = new DateTime();
  87. $diff = $date->diff((clone $date)->modify('3 weeks'));
  88. $ci = CarbonInterval::create(4, 3, 6, 7, 8, 10, 11)->add($diff);
  89. $this->assertCarbonInterval($ci, 4, 3, 70, 8, 10, 11);
  90. }
  91. public function testAddWithRawNegativeDiffDateInterval()
  92. {
  93. date_default_timezone_set('UTC');
  94. $date = new DateTime();
  95. $diff = $date->diff((clone $date)->modify('-3 weeks'));
  96. $ci = CarbonInterval::create(4, 3, 6, 7, 8, 10, 11)->add($diff);
  97. $this->assertCarbonInterval($ci, 4, 3, 28, 8, 10, 11);
  98. }
  99. public static function dataForAddsResults(): Generator
  100. {
  101. yield [5, 2, 7];
  102. yield [-5, -2, -7];
  103. yield [-5, 2, -3];
  104. yield [5, -2, 3];
  105. yield [2, 5, 7];
  106. yield [-2, -5, -7];
  107. yield [-2, 5, 3];
  108. yield [2, -5, -3];
  109. }
  110. /**
  111. * @dataProvider \Tests\CarbonInterval\AddTest::dataForAddsResults
  112. *
  113. * @param int $base
  114. * @param int $increment
  115. * @param int $expectedResult
  116. */
  117. public function testAddSign($base, $increment, $expectedResult)
  118. {
  119. $interval = new CarbonInterval();
  120. $interval->hours(abs($base));
  121. if ($base < 0) {
  122. $interval->invert();
  123. }
  124. $add = new CarbonInterval();
  125. $add->hours(abs($increment));
  126. if ($increment < 0) {
  127. $add->invert();
  128. }
  129. $interval->add($add);
  130. $this->assertGreaterThanOrEqual(0, $interval->hours);
  131. $actualResult = ($interval->invert ? -1 : 1) * $interval->hours;
  132. $this->assertSame($expectedResult, $actualResult);
  133. }
  134. public function testAddAndSubMultipleFormats()
  135. {
  136. $this->assertCarbonInterval(CarbonInterval::day()->add('hours', 3), 0, 0, 1, 3, 0, 0);
  137. $this->assertCarbonInterval(CarbonInterval::day()->add(5, 'hours'), 0, 0, 1, 5, 0, 0);
  138. $this->assertCarbonInterval(CarbonInterval::day()->add(3, '4 hours'), 0, 0, 1, 12, 0, 0);
  139. $this->assertCarbonInterval(CarbonInterval::day()->add(-5, 'hours'), 0, 0, 1, -5, 0, 0);
  140. $this->assertCarbonInterval(CarbonInterval::hours(4)->add('hour'), 0, 0, 0, 5, 0, 0);
  141. $this->assertCarbonInterval(CarbonInterval::hours(4)->add(new DateInterval('P5D')), 0, 0, 5, 4, 0, 0);
  142. $this->assertCarbonInterval(CarbonInterval::hours(4)->add(CarbonInterval::minutes(30)), 0, 0, 0, 4, 30, 0);
  143. $this->assertCarbonInterval(CarbonInterval::day()->sub('hours', 3), 0, 0, 1, -3, 0, 0);
  144. $this->assertCarbonInterval(CarbonInterval::day()->subtract(5, 'hours'), 0, 0, 1, -5, 0, 0);
  145. $this->assertCarbonInterval(CarbonInterval::day()->subtract(3, '4 hours'), 0, 0, 1, -12, 0, 0);
  146. $this->assertCarbonInterval(CarbonInterval::day()->subtract(-5, 'hours'), 0, 0, 1, 5, 0, 0);
  147. $this->assertCarbonInterval(CarbonInterval::hours(4)->sub('hour'), 0, 0, 0, 3, 0, 0);
  148. $this->assertCarbonInterval(CarbonInterval::hours(4)->subtract(new DateInterval('P5D')), 0, 0, -5, 4, 0, 0);
  149. $this->assertCarbonInterval(CarbonInterval::hours(4)->sub(CarbonInterval::minutes(30)), 0, 0, 0, 4, -30, 0);
  150. }
  151. public function testAddWrongFormat()
  152. {
  153. $this->expectExceptionObject(new InvalidArgumentException(
  154. 'This type of data cannot be added/subtracted.'
  155. ));
  156. CarbonInterval::day()->add(Carbon::now());
  157. }
  158. public function testConvertDate()
  159. {
  160. $this->assertCarbon(CarbonInterval::days(3)->convertDate(new DateTime('2020-06-14')), 2020, 6, 17, 0, 0, 0);
  161. $this->assertCarbon(CarbonInterval::days(3)->convertDate(new DateTimeImmutable('2020-06-14')), 2020, 6, 17, 0, 0, 0);
  162. $this->assertCarbon(CarbonInterval::days(3)->convertDate(new DateTime('2020-06-14'), true), 2020, 6, 11, 0, 0, 0);
  163. $this->assertCarbon(CarbonInterval::days(3)->convertDate(new DateTimeImmutable('2020-06-14'), true), 2020, 6, 11, 0, 0, 0);
  164. }
  165. public function testMagicAddAndSubMethods()
  166. {
  167. $this->assertCarbonInterval(CarbonInterval::days(3)->addWeeks(2), 0, 0, 17, 0, 0, 0);
  168. $this->assertCarbonInterval(CarbonInterval::weeks(3)->addDays(2), 0, 0, 23, 0, 0, 0);
  169. $this->assertCarbonInterval(CarbonInterval::weeks(3)->subDays(2), 0, 0, 19, 0, 0, 0);
  170. $this->assertCarbonInterval(CarbonInterval::hours(2)->subMinutes(15), 0, 0, 0, 2, -15, 0);
  171. $this->assertCarbonInterval(CarbonInterval::hours(2)->subMinutes(15)->cascade(), 0, 0, 0, 1, 45, 0);
  172. }
  173. public function testPlus()
  174. {
  175. $this->assertCarbonInterval(CarbonInterval::days(3)->plus(0, 0, 2, 0, 26), 0, 0, 17, 26, 0, 0);
  176. $this->assertCarbonInterval(CarbonInterval::days(3)->plus(0, 0, 0.25), 0, 0, 4, 18, 0, 0);
  177. $interval = CarbonInterval::days(3)->plus(0, 0, 0.25)->plus(0, 0, 0.25)->cascade();
  178. $this->assertCarbonInterval($interval, 0, 0, 6, 12, 0, 0);
  179. }
  180. /**
  181. * @requires PHP >= 8.0
  182. */
  183. public function testPlusWithPHP8Syntax()
  184. {
  185. $interval = eval('use Carbon\CarbonInterval;return CarbonInterval::days(3)->plus(weeks: 2, hours: 26);');
  186. $this->assertCarbonInterval($interval, 0, 0, 17, 26, 0, 0);
  187. }
  188. public function testMinus()
  189. {
  190. $this->assertCarbonInterval(CarbonInterval::days(3)->minus(0, 0, 2, 0, 26), 0, 0, 11, 26, 0, 0, 0, true);
  191. }
  192. /**
  193. * @requires PHP >= 8.0
  194. */
  195. public function testMinusWithPHP8Syntax()
  196. {
  197. $interval = eval('use Carbon\CarbonInterval;return CarbonInterval::days(3)->minus(weeks: 2, hours: 26);');
  198. $this->assertCarbonInterval($interval, 0, 0, 11, 26, 0, 0, 0, true);
  199. }
  200. }