Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- use Carbon\Carbon;
- date_default_timezone_set('Europe/Moscow');
- require 'vendor/autoload.php';
- class Parking
- {
- protected $baseHourPrice;
- public function __construct($baseHourPrice)
- {
- $this->baseHourPrice = $baseHourPrice;
- }
- /**
- * @var Rule[]
- */
- private $rules = [];
- public function addRule(Rule $rule)
- {
- $this->rules[] = $rule;
- return $this;
- }
- function calculate(Carbon $begin, Carbon $end)
- {
- /**
- * dates list when something was changed
- * @var $dates Carbon[]
- */
- $dates = [$begin->getTimestamp() => $begin];
- $current = $begin->copy();
- while ($current < $end) {
- foreach ($this->rules as $rule) {
- if ($rule->shouldBeApplied($current)) {
- foreach ([$rule->getBegin($current), $rule->getEnd($current)] as $point) {
- if (!isset($dates[$point->getTimestamp()]) && $point->between($begin, $end)) {
- $dates[$point->getTimestamp()] = $point;
- }
- }
- }
- }
- $current = $current->copy()->addDay(1);
- }
- $dates[$end->getTimestamp()] = $end;
- ksort($dates);
- // calculate result
- $previous = null;
- $total = 0;
- foreach ($dates as $current) {
- if ($previous) {
- $hours = $current->diffInMinutes($previous) / 60;
- $sum = $this->baseHourPrice * $hours;
- $rules = [];
- foreach ($this->rules as $rule) {
- if ($rule->shouldBeApplied($current)) {
- if ($rule->getBegin($current) < $current && $rule->getEnd($current) >= $current) {
- $sum = $rule->changeSum($sum, $hours);
- $rules[] = get_class($rule);
- }
- }
- }
- echo $previous, ' - ', $current, PHP_EOL;
- echo json_encode(compact('hours', 'sum', 'rules')), PHP_EOL, PHP_EOL;
- $total += $sum;
- }
- $previous = $current;
- }
- echo 'Total is: ', $total, PHP_EOL;
- return $total;
- }
- }
- interface Rule
- {
- public function shouldBeApplied(Carbon $date);
- public function getBegin(Carbon $date);
- public function getEnd(Carbon $date);
- public function changeSum($sum);
- }
- /**
- * Pay twice when use parking during hot hours
- * Class HighLoadRule
- */
- class HighLoadRule implements Rule
- {
- function shouldBeApplied(Carbon $date)
- {
- return $date->isWeekday();
- }
- function getBegin(Carbon $date)
- {
- return $date->copy()->setTime(17, 0, 0);
- }
- function getEnd(Carbon $date)
- {
- return $date->copy()->setTime(22, 0, 0);
- }
- function changeSum($sum)
- {
- return $sum * 2;
- }
- }
- class WeekendRule implements Rule
- {
- function shouldBeApplied(Carbon $date)
- {
- return $date->isWeekend();
- }
- function getBegin(Carbon $date)
- {
- return $date->copy()->setTime(0, 0, 0);
- }
- function getEnd(Carbon $date)
- {
- return $date->copy()->setTime(24, 0, 0);
- }
- function changeSum($sum)
- {
- return $sum / 2;
- }
- }
- class GoldHoursRule implements Rule
- {
- function shouldBeApplied(Carbon $date)
- {
- return true;
- }
- function getBegin(Carbon $date)
- {
- return $date->copy()->setTime(18, 0, 0);
- }
- function getEnd(Carbon $date)
- {
- return $date->copy()->setTime(19, 0, 0);
- }
- function changeSum($sum)
- {
- return $sum * 3;
- }
- }
- class GoodMorningRule implements Rule
- {
- function shouldBeApplied(Carbon $date)
- {
- return true;
- }
- function getBegin(Carbon $date)
- {
- return $date->copy()->setTime(9, 0, 0);
- }
- function getEnd(Carbon $date)
- {
- return $date->copy()->setTime(10, 0, 0);
- }
- function changeSum($sum)
- {
- return 0;
- }
- }
- $result = with(new Parking(120)) // parking with 120 RUB per hours base price
- ->addRule(new WeekendRule()) // on weekdays from 17 to 22 pay twice higher
- ->addRule(new HighLoadRule()) // on weekends pay twice lower
- ->addRule(new GoldHoursRule()) // any day from 18 to 19 price multiplies by 3
- ->addRule(new GoodMorningRule()) // any day from 9 to 10 parking is free
- ->calculate(
- // 2015-07-24 13:30:00
- Carbon::createFromTime(13, 30, 00)->setDate(2015, 7, 23),
- // 2015-07-25 17:00:00
- Carbon::createFromTime(21, 00, 00)->setDate(2015, 7, 25)
- );
- //
- // 2015-07-23 13:30:00 - 2015-07-23 17:00:00
- // {"hours":3.5,"sum":420,"rules":[]}
- //
- // 2015-07-23 17:00:00 - 2015-07-23 18:00:00
- // {"hours":1,"sum":240,"rules":["HighLoadRule"]}
- //
- // 2015-07-23 18:00:00 - 2015-07-23 19:00:00
- // {"hours":1,"sum":720,"rules":["HighLoadRule","GoldHoursRule"]}
- //
- // 2015-07-23 19:00:00 - 2015-07-23 22:00:00
- // {"hours":3,"sum":720,"rules":["HighLoadRule"]}
- //
- // 2015-07-23 22:00:00 - 2015-07-24 09:00:00
- // {"hours":11,"sum":1320,"rules":[]}
- //
- // 2015-07-24 09:00:00 - 2015-07-24 10:00:00
- // {"hours":1,"sum":0,"rules":["GoodMorningRule"]}
- //
- // 2015-07-24 10:00:00 - 2015-07-24 17:00:00
- // {"hours":7,"sum":840,"rules":[]}
- //
- // 2015-07-24 17:00:00 - 2015-07-24 18:00:00
- // {"hours":1,"sum":240,"rules":["HighLoadRule"]}
- //
- // 2015-07-24 18:00:00 - 2015-07-24 19:00:00
- // {"hours":1,"sum":720,"rules":["HighLoadRule","GoldHoursRule"]}
- //
- // 2015-07-24 19:00:00 - 2015-07-24 22:00:00
- // {"hours":3,"sum":720,"rules":["HighLoadRule"]}
- //
- // 2015-07-24 22:00:00 - 2015-07-25 00:00:00
- // {"hours":2,"sum":240,"rules":[]}
- //
- // 2015-07-25 00:00:00 - 2015-07-25 09:00:00
- // {"hours":9,"sum":540,"rules":["WeekendRule"]}
- //
- // 2015-07-25 09:00:00 - 2015-07-25 10:00:00
- // {"hours":1,"sum":0,"rules":["WeekendRule","GoodMorningRule"]}
- //
- // 2015-07-25 10:00:00 - 2015-07-25 18:00:00
- // {"hours":8,"sum":480,"rules":["WeekendRule"]}
- //
- // 2015-07-25 18:00:00 - 2015-07-25 19:00:00
- // {"hours":1,"sum":180,"rules":["WeekendRule","GoldHoursRule"]}
- //
- // 2015-07-25 19:00:00 - 2015-07-25 21:00:00
- // {"hours":2,"sum":120,"rules":["WeekendRule"]}
- //
- // Total is: 7500
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement