RoundingTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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\CarbonPeriod;
  12. use Carbon\CarbonInterval;
  13. use InvalidArgumentException;
  14. use Tests\AbstractTestCase;
  15. class RoundingTest extends AbstractTestCase
  16. {
  17. public function testThrowsExceptionForCompositeInterval()
  18. {
  19. $this->expectExceptionObject(new InvalidArgumentException(
  20. 'Rounding is only possible with single unit intervals.'
  21. ));
  22. $periodClass = $this->periodClass;
  23. $periodClass::days(2)->round('2 hours 50 minutes');
  24. }
  25. public function testFloor()
  26. {
  27. $periodClass = $this->periodClass;
  28. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817')->floor();
  29. $this->assertSame('01 00:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  30. $this->assertSame('2019-02-01 00:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  31. $this->assertSame('2019-12-12 00:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  32. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '1 hour')->floor();
  33. $this->assertSame('2019-02-01 12:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  34. $this->assertSame('2019-12-12 03:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  35. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->floor();
  36. $this->assertSame('2019-02-01 12:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  37. $this->assertSame('2019-12-12 02:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  38. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817')->floor('hour');
  39. $this->assertSame('01 00:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  40. $this->assertSame('2019-02-01 12:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  41. $this->assertSame('2019-12-12 03:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  42. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '140 minutes')->floor('hour');
  43. $this->assertSame('00 02:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  44. $this->assertSame('2019-02-01 12:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  45. $this->assertSame('2019-12-12 03:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  46. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '1 hour')->floor(CarbonInterval::minutes(15));
  47. $this->assertSame('2019-02-01 12:45:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  48. $this->assertSame('2019-12-12 03:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  49. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->floorUnit('minute', 10);
  50. $this->assertSame('2019-02-01 12:50:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  51. $this->assertSame('2019-12-12 03:10:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  52. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->floorMinutes(10);
  53. $this->assertSame('2019-02-01 12:50:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  54. $this->assertSame('2019-12-12 03:10:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  55. }
  56. public function testCeil()
  57. {
  58. $periodClass = $this->periodClass;
  59. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817')->ceil();
  60. $this->assertSame('01 00:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  61. $this->assertSame('2019-02-02 00:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  62. $this->assertSame('2019-12-13 00:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  63. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '1 hour')->ceil();
  64. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  65. $this->assertSame('2019-12-12 04:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  66. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->ceil();
  67. $this->assertSame('2019-02-01 14:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  68. $this->assertSame('2019-12-12 04:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  69. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817')->ceil('hour');
  70. $this->assertSame('01 00:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  71. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  72. $this->assertSame('2019-12-12 04:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  73. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '140 minutes')->ceil('hour');
  74. $this->assertSame('00 03:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  75. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  76. $this->assertSame('2019-12-12 04:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  77. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '1 hour')->ceil(CarbonInterval::minutes(15));
  78. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  79. $this->assertSame('2019-12-12 03:15:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  80. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->ceilUnit('minute', 10);
  81. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  82. $this->assertSame('2019-12-12 03:20:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  83. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->ceilMinutes(10);
  84. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  85. $this->assertSame('2019-12-12 03:20:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  86. }
  87. public function testRound()
  88. {
  89. $periodClass = $this->periodClass;
  90. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817')->round();
  91. $this->assertSame('01 00:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  92. $this->assertSame('2019-02-02 00:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  93. $this->assertSame('2019-12-12 00:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  94. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '1 hour')->round();
  95. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  96. $this->assertSame('2019-12-12 03:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  97. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->round();
  98. $this->assertSame('2019-02-01 12:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  99. $this->assertSame('2019-12-12 04:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  100. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817')->round('hour');
  101. $this->assertSame('01 00:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  102. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  103. $this->assertSame('2019-12-12 03:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  104. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '140 minutes')->round('hour');
  105. $this->assertSame('00 02:00:00.000000', $period->getDateInterval()->format('%D %H:%I:%S.%F'));
  106. $this->assertSame('2019-02-01 13:00:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  107. $this->assertSame('2019-12-12 03:00:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  108. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '1 hour')->round(CarbonInterval::minutes(15));
  109. $this->assertSame('2019-02-01 12:45:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  110. $this->assertSame('2019-12-12 03:15:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  111. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->roundUnit('minute', 10);
  112. $this->assertSame('2019-02-01 12:50:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  113. $this->assertSame('2019-12-12 03:10:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  114. $period = $periodClass::create('2019-02-01 12:52:23', '2019-12-12 03:12:44.817', '2 hours')->roundMinutes(10);
  115. $this->assertSame('2019-02-01 12:50:00.000000', $period->getStartDate()->format('Y-m-d H:i:s.u'));
  116. $this->assertSame('2019-12-12 03:10:00.000000', $period->getEndDate()->format('Y-m-d H:i:s.u'));
  117. }
  118. public function testRoundCalculatedEnd()
  119. {
  120. $periodClass = $this->periodClass;
  121. $period = $periodClass::create('2019-02-01 12:52:23.123456', '3 hours')->setRecurrences(3);
  122. $this->assertSame('2019-02-01 18:00:00.000000', $period->calculateEnd('round')->format('Y-m-d H:i:s.u'));
  123. $this->assertSame('2019-02-01 18:52:23.123456', $period->calculateEnd()->format('Y-m-d H:i:s.u'));
  124. $period = $periodClass::create('2019-02-01 12:52:23.123456', '3 hours')
  125. ->setRecurrences(3)
  126. ->addFilter(function ($date) {
  127. return $date->hour % 2;
  128. });
  129. $this->assertSame('2019-02-02 03:00:00.000000', $period->calculateEnd('round')->format('Y-m-d H:i:s.u'));
  130. $this->assertSame('2019-02-02 03:52:23.123456', $period->calculateEnd()->format('Y-m-d H:i:s.u'));
  131. }
  132. }