diff --git a/src/Timesheet/Rounding/CeilRounding.php b/src/Timesheet/Rounding/CeilRounding.php new file mode 100644 index 00000000..c5fefa9f --- /dev/null +++ b/src/Timesheet/Rounding/CeilRounding.php @@ -0,0 +1,78 @@ +getBegin()->getTimestamp(); + $seconds = $minutes * 60; + $diff = $timestamp % $seconds; + + if (0 === $diff) { + return; + } + + $record->getBegin()->setTimestamp($timestamp - $diff + $seconds); + } + + /** + * @param Timesheet $record + * @param int $minutes + */ + public function roundEnd(Timesheet $record, $minutes) + { + if ($minutes <= 0) { + return; + } + + $timestamp = $record->getEnd()->getTimestamp(); + $seconds = $minutes * 60; + $diff = $timestamp % $seconds; + + if (0 === $diff) { + return; + } + + $record->getEnd()->setTimestamp($timestamp - $diff + $seconds); + } + + /** + * @param Timesheet $record + * @param int $minutes + */ + public function roundDuration(Timesheet $record, $minutes) + { + if ($minutes <= 0) { + return; + } + + $timestamp = $record->getDuration(); + $seconds = $minutes * 60; + $diff = $timestamp % $seconds; + + if (0 === $diff) { + return; + } + + $record->setDuration($timestamp - $diff + $seconds); + } +} diff --git a/src/Timesheet/Rounding/FloorRounding.php b/src/Timesheet/Rounding/FloorRounding.php new file mode 100644 index 00000000..3e360885 --- /dev/null +++ b/src/Timesheet/Rounding/FloorRounding.php @@ -0,0 +1,78 @@ +getBegin()->getTimestamp(); + $seconds = $minutes * 60; + $diff = $timestamp % $seconds; + + if (0 === $diff) { + return; + } + + $record->getBegin()->setTimestamp($timestamp - $diff); + } + + /** + * @param Timesheet $record + * @param int $minutes + */ + public function roundEnd(Timesheet $record, $minutes) + { + if ($minutes <= 0) { + return; + } + + $timestamp = $record->getEnd()->getTimestamp(); + $seconds = $minutes * 60; + $diff = $timestamp % $seconds; + + if (0 === $diff) { + return; + } + + $record->getEnd()->setTimestamp($timestamp - $diff); + } + + /** + * @param Timesheet $record + * @param int $minutes + */ + public function roundDuration(Timesheet $record, $minutes) + { + if ($minutes <= 0) { + return; + } + + $timestamp = $record->getDuration(); + $seconds = $minutes * 60; + $diff = $timestamp % $seconds; + + if (0 === $diff) { + return; + } + + $record->setDuration($timestamp - $diff); + } +} diff --git a/tests/Timesheet/Rounding/CeilRoundingTest.php b/tests/Timesheet/Rounding/CeilRoundingTest.php new file mode 100644 index 00000000..aaaf773b --- /dev/null +++ b/tests/Timesheet/Rounding/CeilRoundingTest.php @@ -0,0 +1,152 @@ +setBegin($start); + $record->setEnd($end); + $this->assertEquals(0, $record->getDuration()); + + $record->setDuration($record->getEnd()->getTimestamp() - $record->getBegin()->getTimestamp()); + + $sut = new CeilRounding(); + $sut->roundBegin($record, $roundBegin); + $sut->roundEnd($record, $roundEnd); + $record->setDuration($record->getEnd()->getTimestamp() - $record->getBegin()->getTimestamp()); + $sut->roundDuration($record, $roundDuration); + + $this->assertEquals($expectedStart->getTimestamp(), $record->getBegin()->getTimestamp()); + $this->assertEquals($expectedEnd->getTimestamp(), $record->getEnd()->getTimestamp()); + $this->assertEquals($expectedDuration, $record->getDuration()); + } + + public function getTestData() + { + $start = new \DateTime(); + $start->setTime(12, 0, 0); + + return [ + [ + 0, + 0, + 0, + $start, + (clone $start)->setTimestamp($start->getTimestamp() + 1837), + $start, + (clone $start)->setTimestamp($start->getTimestamp() + 1837), + 1837 + ], + [ + 15, + 15, + 0, + (clone $start)->setTime(12, 17, 35), + (clone $start)->setTime(13, 32, 52), + (clone $start)->setTime(12, 30, 00), + (clone $start)->setTime(13, 45, 00), + 4500 + ], + [ + 0, + 0, + 0, + (clone $start)->setTime(12, 17, 35), + (clone $start)->setTime(13, 32, 52), + (clone $start)->setTime(12, 17, 35), + (clone $start)->setTime(13, 32, 52), + 4517 + ], + [ + 1, + 1, + 0, + (clone $start)->setTime(12, 17, 35), + (clone $start)->setTime(13, 32, 52), + (clone $start)->setTime(12, 18, 00), + (clone $start)->setTime(13, 33, 00), + 4500 + ], + [ + 0, + 0, + 30, + (clone $start)->setTime(12, 10, 51), + (clone $start)->setTime(14, 40, 52), + (clone $start)->setTime(12, 10, 51), + (clone $start)->setTime(14, 40, 52), + 10800 + ], + [ + 0, + 1, + 30, + (clone $start)->setTime(12, 27, 35), // 12:15 + (clone $start)->setTime(14, 32, 52), // 14:33 => 2:18 => 2:30 + (clone $start)->setTime(12, 27, 35), + (clone $start)->setTime(14, 33, 00), + 9000 + ], + [ + 15, + 0, + 30, + (clone $start)->setTime(12, 27, 35), // 12:15 + (clone $start)->setTime(14, 32, 52), // 14:33 => 2:18 (second duration will not be rounded) + (clone $start)->setTime(12, 30, 00), // 12:15 + (clone $start)->setTime(14, 32, 52), // 14:33 => 2:18 (second duration will not be rounded) + 9000 + ], + [ + 0, + 0, + 1, + (clone $start)->setTime(12, 27, 35), // no diff, to test ... + (clone $start)->setTime(12, 27, 35), // ... that no rounding is applied + (clone $start)->setTime(12, 27, 35), // no diff, to test ... + (clone $start)->setTime(12, 27, 35), // ... that no rounding is applied + 0 + ], + [ + 1, + 1, + 1, + (clone $start)->setTime(12, 27, 00), // no diff, to test ... + (clone $start)->setTime(12, 27, 00), // ... that no rounding is applied + (clone $start)->setTime(12, 27, 00), // no diff, to test ... + (clone $start)->setTime(12, 27, 00), // ... that no rounding is applied + 0 + ], + [ + 0, + 0, + 0, + (clone $start)->setTime(12, 27, 35), // no diff, to test ... + (clone $start)->setTime(12, 27, 35), // ... that no rounding is applied + (clone $start)->setTime(12, 27, 35), // no diff, to test ... + (clone $start)->setTime(12, 27, 35), // ... that no rounding is applied + 0 + ], + ]; + } +} diff --git a/tests/Timesheet/Rounding/FloorRoundingTest.php b/tests/Timesheet/Rounding/FloorRoundingTest.php new file mode 100644 index 00000000..20201940 --- /dev/null +++ b/tests/Timesheet/Rounding/FloorRoundingTest.php @@ -0,0 +1,152 @@ +setBegin($start); + $record->setEnd($end); + $this->assertEquals(0, $record->getDuration()); + + $record->setDuration($record->getEnd()->getTimestamp() - $record->getBegin()->getTimestamp()); + + $sut = new FloorRounding(); + $sut->roundBegin($record, $roundBegin); + $sut->roundEnd($record, $roundEnd); + $record->setDuration($record->getEnd()->getTimestamp() - $record->getBegin()->getTimestamp()); + $sut->roundDuration($record, $roundDuration); + + $this->assertEquals($expectedStart->getTimestamp(), $record->getBegin()->getTimestamp()); + $this->assertEquals($expectedEnd->getTimestamp(), $record->getEnd()->getTimestamp()); + $this->assertEquals($expectedDuration, $record->getDuration()); + } + + public function getTestData() + { + $start = new \DateTime(); + $start->setTime(12, 0, 0); + + return [ + [ + 0, + 0, + 0, + $start, + (clone $start)->setTimestamp($start->getTimestamp() + 1837), + $start, + (clone $start)->setTimestamp($start->getTimestamp() + 1837), + 1837 + ], + [ + 15, + 15, + 0, + (clone $start)->setTime(12, 17, 35), + (clone $start)->setTime(13, 32, 52), + (clone $start)->setTime(12, 15, 00), + (clone $start)->setTime(13, 30, 00), + 4500 + ], + [ + 0, + 0, + 0, + (clone $start)->setTime(12, 17, 35), + (clone $start)->setTime(13, 32, 52), + (clone $start)->setTime(12, 17, 35), + (clone $start)->setTime(13, 32, 52), + 4517 + ], + [ + 1, + 1, + 0, + (clone $start)->setTime(12, 17, 35), + (clone $start)->setTime(13, 32, 52), + (clone $start)->setTime(12, 17, 00), + (clone $start)->setTime(13, 32, 00), + 4500 + ], + [ + 0, + 0, + 30, + (clone $start)->setTime(12, 10, 51), + (clone $start)->setTime(14, 40, 52), + (clone $start)->setTime(12, 10, 51), + (clone $start)->setTime(14, 40, 52), + 9000 + ], + [ + 0, + 1, + 30, + (clone $start)->setTime(12, 27, 35), // 12:15 + (clone $start)->setTime(14, 32, 52), // 14:33 => 2:18 => 2:30 + (clone $start)->setTime(12, 27, 35), + (clone $start)->setTime(14, 32, 00), + 7200 + ], + [ + 15, + 0, + 30, + (clone $start)->setTime(12, 27, 35), // 12:15 + (clone $start)->setTime(14, 32, 52), // 14:33 => 2:18 (second duration will not be rounded) + (clone $start)->setTime(12, 15, 00), // 12:15 + (clone $start)->setTime(14, 32, 52), // 14:33 => 2:18 (second duration will not be rounded) + 7200 + ], + [ + 0, + 0, + 1, + (clone $start)->setTime(12, 27, 35), // no diff, to test ... + (clone $start)->setTime(12, 27, 35), // ... that no rounding is applied + (clone $start)->setTime(12, 27, 35), // no diff, to test ... + (clone $start)->setTime(12, 27, 35), // ... that no rounding is applied + 0 + ], + [ + 1, + 1, + 1, + (clone $start)->setTime(12, 27, 00), // no diff, to test ... + (clone $start)->setTime(12, 27, 00), // ... that no rounding is applied + (clone $start)->setTime(12, 27, 00), // no diff, to test ... + (clone $start)->setTime(12, 27, 00), // ... that no rounding is applied + 0 + ], + [ + 0, + 0, + 0, + (clone $start)->setTime(12, 27, 35), // no diff, to test ... + (clone $start)->setTime(12, 27, 35), // ... that no rounding is applied + (clone $start)->setTime(12, 27, 35), // no diff, to test ... + (clone $start)->setTime(12, 27, 35), // ... that no rounding is applied + 0 + ], + ]; + } +}