neil_pearce

daysIterator

Feb 14th, 2023
1,099
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.39 KB | Source Code | 0 0
  1. <?php
  2. declare(strict_types=1);
  3.  
  4. class daysIterator implements Iterator
  5. {
  6.     private int $daysOffset = 0;
  7.     private ?DateInterval $dateInterval = null;
  8.     private ?DateTimeImmutable $endDate = null;
  9.     private ?DateTimeImmutable $startDate = null;
  10.  
  11.  
  12.     public function current(): mixed
  13.     {
  14.         /*
  15.          * Compute current date as number of days offset from start date.
  16.          * 'invert' indicates whether a negative interval
  17.          */
  18.         $days = new DateInterval(sprintf('P%dD', $this->daysOffset));
  19.         $date = $this->dateInterval->invert == 0 ? $this->startDate->add($days)
  20.                                                  : $this->startDate->sub($days);
  21.  
  22.         /* reformat current date and return date fields as an integer array */
  23.         $current = explode('/', $date->format('d/m/Y'));
  24.  
  25.         return ['day'   => (int) $current[0],
  26.                 'month' => (int) $current[1],
  27.                 'year'  => (int) $current[2],
  28.                ];
  29.     }
  30.  
  31.  
  32.     public function key(): mixed
  33.     {
  34.         return $this->daysOffset;
  35.     }
  36.  
  37.  
  38.     public function next(): void
  39.     {
  40.         $this->daysOffset++;
  41.     }
  42.  
  43.  
  44.     public function rewind(): void
  45.     {
  46.         $this->daysOffset = 0;
  47.     }
  48.  
  49.  
  50.     public function valid(): bool
  51.     {
  52.         $this->dateInterval
  53.         or throw new LogicException('Both start and end dates must be specified');
  54.  
  55.         return $this->daysOffset <= $this->dateInterval->days;
  56.     }
  57.  
  58.  
  59.     public function setEndDate(string $endDate)
  60.     {
  61.         $this->endDate = new DateTimeImmutable($endDate);
  62.  
  63.         $this->dateInterval();
  64.     }
  65.  
  66.  
  67.     public function setStartDate(string $startDate)
  68.     {
  69.         $this->startDate = new DateTimeImmutable($startDate);
  70.  
  71.         $this->dateInterval();
  72.     }
  73.  
  74.  
  75.     private function dateInterval()
  76.     {
  77.         if (
  78.             ! is_null($this->startDate)
  79.             && ! is_null($this->endDate)
  80.         ) {
  81.             /* determine interval between dates */
  82.             $this->dateInterval = $this->startDate->diff($this->endDate);
  83.  
  84.             $this->daysOffset = 0;  // holds number of days from start date
  85.         } else {
  86.             $this->dateInterval = null;
  87.         }
  88.     }
  89. }
  90.  
  91.  
  92. $eol = empty($argc) ? '<br>' : PHP_EOL;  // determine end of line
  93.  
  94.  
  95. $days = new daysIterator();
  96. $days->setStartDate('2023-02-06');
  97. $days->setEndDate('2023-02-01');
  98.  
  99. foreach ($days as $key => $current) {
  100.     var_dump($key, $current);
  101.     echo $eol;
  102. }
  103.  
  104.  
  105. /**************************************************************************************************/
  106.  
  107.  
  108. class daysIterator_v2 implements Iterator
  109. {
  110.     private int $daysOffset;
  111.     private DateInterval $dateInterval;
  112.     private DateTimeImmutable $startDate;
  113.  
  114.  
  115.     public function __construct(string $startDate, string $endDate)
  116.     {
  117.         $this->startDate = new DateTimeImmutable($startDate);
  118.  
  119.         /* determine interval between dates */
  120.         $this->dateInterval = $this->startDate->diff(new DateTime($endDate));
  121.  
  122.         $this->daysOffset = 0;  // holds number of days from start date
  123.     }
  124.  
  125.  
  126.     public function current(): mixed
  127.     {
  128.         /*
  129.          * Compute current date as number of days offset from start date.
  130.          * 'invert' indicates whether a negative interval
  131.          */
  132.         $days = new DateInterval(sprintf('P%dD', $this->daysOffset));
  133.         $date = $this->dateInterval->invert == 0 ? $this->startDate->add($days)
  134.                                                  : $this->startDate->sub($days);
  135.  
  136.         /* reformat current date and return date fields as an integer array */
  137.         $current = explode('/', $date->format('d/m/Y'));
  138.  
  139.         return ['day'   => (int) $current[0],
  140.                 'month' => (int) $current[1],
  141.                 'year'  => (int) $current[2],
  142.                ];
  143.     }
  144.  
  145.  
  146.     public function key(): mixed
  147.     {
  148.         return $this->daysOffset;
  149.     }
  150.  
  151.  
  152.     public function next(): void
  153.     {
  154.         $this->daysOffset++;
  155.     }
  156.  
  157.  
  158.     public function rewind(): void
  159.     {
  160.         $this->daysOffset = 0;
  161.     }
  162.  
  163.  
  164.     public function valid(): bool
  165.     {
  166.         return $this->daysOffset <= $this->dateInterval->days;
  167.     }
  168. }
  169.  
  170.  
  171. $eol = empty($argc) ? '<br>' : PHP_EOL;  // determine end of line
  172.  
  173.  
  174. foreach (new daysIterator_v2('2023-02-06', '2023-02-20') as $key => $current) {
  175.     var_dump($key, $current);
  176.     echo $eol;
  177. }
  178.  
Advertisement
Add Comment
Please, Sign In to add comment