| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2020-06-30 19:05:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * ParseDateString.php | 
					
						
							|  |  |  |  * Copyright (c) 2020 james@firefly-iii.org | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is part of Firefly III (https://github.com/firefly-iii). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation, either version 3 of the | 
					
						
							|  |  |  |  * License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | declare(strict_types=1); | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | namespace FireflyIII\Support; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | use Carbon\Carbon; | 
					
						
							| 
									
										
										
										
											2024-04-02 15:40:33 +02:00
										 |  |  | use Carbon\CarbonInterface; | 
					
						
							| 
									
										
										
										
											2023-12-09 20:12:34 +01:00
										 |  |  | use Carbon\Exceptions\InvalidFormatException; | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | use FireflyIII\Exceptions\FireflyException; | 
					
						
							| 
									
										
										
										
											2023-12-09 20:12:34 +01:00
										 |  |  | use Illuminate\Support\Facades\Log; | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  | use function Safe\preg_match; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Class ParseDateString | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class ParseDateString | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-09-28 07:35:57 +02:00
										 |  |  |     private array $keywords | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |         = [ | 
					
						
							|  |  |  |             'today', | 
					
						
							|  |  |  |             'yesterday', | 
					
						
							|  |  |  |             'tomorrow', | 
					
						
							|  |  |  |             'start of this week', | 
					
						
							|  |  |  |             'end of this week', | 
					
						
							|  |  |  |             'start of this month', | 
					
						
							|  |  |  |             'end of this month', | 
					
						
							|  |  |  |             'start of this quarter', | 
					
						
							|  |  |  |             'end of this quarter', | 
					
						
							|  |  |  |             'start of this year', | 
					
						
							|  |  |  |             'end of this year', | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |     public function isDateRange(string $date): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $date = strtolower($date); | 
					
						
							|  |  |  |         // not 10 chars:
 | 
					
						
							|  |  |  |         if (10 !== strlen($date)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // all x'es
 | 
					
						
							|  |  |  |         if ('xxxx-xx-xx' === strtolower($date)) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         // no x'es
 | 
					
						
							|  |  |  |         if (!str_contains($date, 'xx') && !str_contains($date, 'xxxx')) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2021-09-18 10:21:29 +02:00
										 |  |  |      * @throws FireflyException | 
					
						
							| 
									
										
										
										
											2023-12-22 20:12:38 +01:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2025-01-03 15:53:10 +01:00
										 |  |  |      * @SuppressWarnings("PHPMD.NPathComplexity") | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function parseDate(string $date): Carbon | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('parseDate("%s")', $date)); | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |         $date        = strtolower($date); | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |         // parse keywords:
 | 
					
						
							|  |  |  |         if (in_array($date, $this->keywords, true)) { | 
					
						
							|  |  |  |             return $this->parseKeyword($date); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // if regex for YYYY-MM-DD:
 | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |         $pattern     = '/^(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/'; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |         $result      = preg_match($pattern, $date); | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |         if (false !== $result && 0 !== $result) { | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |             return $this->parseDefaultDate($date); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // if + or -:
 | 
					
						
							| 
									
										
										
										
											2021-09-18 10:20:19 +02:00
										 |  |  |         if (str_starts_with($date, '+') || str_starts_with($date, '-')) { | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |             return $this->parseRelativeDate($date); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |         if ('xxxx-xx-xx' === strtolower($date)) { | 
					
						
							| 
									
										
										
										
											2021-12-17 17:27:29 +01:00
										 |  |  |             throw new FireflyException(sprintf('[a] Not a recognised date format: "%s"', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         // can't do a partial year:
 | 
					
						
							| 
									
										
										
										
											2023-02-22 18:03:31 +01:00
										 |  |  |         $substrCount = substr_count(substr($date, 0, 4), 'x'); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |         if (10 === strlen($date) && $substrCount > 0 && $substrCount < 4) { | 
					
						
							| 
									
										
										
										
											2021-12-17 17:27:29 +01:00
										 |  |  |             throw new FireflyException(sprintf('[b] Not a recognised date format: "%s"', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // maybe a date range
 | 
					
						
							| 
									
										
										
										
											2021-09-18 10:20:19 +02:00
										 |  |  |         if (10 === strlen($date) && (str_contains($date, 'xx') || str_contains($date, 'xxxx'))) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('[c] Detected a date range ("%s"), return a fake date.', $date)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |             // very lazy way to parse the date without parsing it, because this specific function
 | 
					
						
							|  |  |  |             // cant handle date ranges.
 | 
					
						
							|  |  |  |             return new Carbon('1984-09-17'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-09-14 20:01:33 +02:00
										 |  |  |         // maybe a year, nothing else?
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |         if (4 === strlen($date) && is_numeric($date) && (int) $date > 1000 && (int) $date <= 3000) { | 
					
						
							| 
									
										
										
										
											2020-09-14 20:01:33 +02:00
										 |  |  |             return new Carbon(sprintf('%d-01-01', $date)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-28 07:35:57 +02:00
										 |  |  |         throw new FireflyException(sprintf('[d] Not a recognised date format: "%s"', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function parseKeyword(string $keyword): Carbon | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $today = today(config('app.timezone'))->startOfDay(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-04 19:43:58 +01:00
										 |  |  |         return match ($keyword) { | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |             default                 => $today, | 
					
						
							|  |  |  |             'yesterday'             => $today->subDay(), | 
					
						
							|  |  |  |             'tomorrow'              => $today->addDay(), | 
					
						
							| 
									
										
										
										
											2024-04-02 15:40:33 +02:00
										 |  |  |             'start of this week'    => $today->startOfWeek(CarbonInterface::MONDAY), | 
					
						
							|  |  |  |             'end of this week'      => $today->endOfWeek(CarbonInterface::SUNDAY), | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |             'start of this month'   => $today->startOfMonth(), | 
					
						
							|  |  |  |             'end of this month'     => $today->endOfMonth(), | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             'start of this quarter' => $today->startOfQuarter(), | 
					
						
							| 
									
										
										
										
											2023-07-15 16:02:42 +02:00
										 |  |  |             'end of this quarter'   => $today->endOfQuarter(), | 
					
						
							|  |  |  |             'start of this year'    => $today->startOfYear(), | 
					
						
							|  |  |  |             'end of this year'      => $today->endOfYear(), | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function parseDefaultDate(string $date): Carbon | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-12-09 20:12:34 +01:00
										 |  |  |         $result = false; | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-09 20:12:34 +01:00
										 |  |  |         try { | 
					
						
							|  |  |  |             $result = Carbon::createFromFormat('Y-m-d', $date); | 
					
						
							| 
									
										
										
										
											2025-01-04 19:43:58 +01:00
										 |  |  |         } catch (InvalidFormatException $e) { | 
					
						
							| 
									
										
										
										
											2023-12-09 20:12:34 +01:00
										 |  |  |             Log::error(sprintf('parseDefaultDate("%s") ran into an error, but dont mind: %s', $date, $e->getMessage())); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (false === $result) { | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |             return today(config('app.timezone'))->startOfDay(); | 
					
						
							| 
									
										
										
										
											2023-11-28 05:31:26 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-28 05:31:26 +01:00
										 |  |  |         return $result; | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function parseRelativeDate(string $date): Carbon | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('Now in parseRelativeDate("%s")', $date)); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $parts     = explode(' ', $date); | 
					
						
							|  |  |  |         $today     = today(config('app.timezone'))->startOfDay(); | 
					
						
							|  |  |  |         $functions = [ | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 'd' => 'subDays', | 
					
						
							|  |  |  |                 'w' => 'subWeeks', | 
					
						
							|  |  |  |                 'm' => 'subMonths', | 
					
						
							|  |  |  |                 'q' => 'subQuarters', | 
					
						
							|  |  |  |                 'y' => 'subYears', | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 'd' => 'addDays', | 
					
						
							|  |  |  |                 'w' => 'addWeeks', | 
					
						
							|  |  |  |                 'm' => 'addMonths', | 
					
						
							|  |  |  |                 'q' => 'addQuarters', | 
					
						
							|  |  |  |                 'y' => 'addYears', | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach ($parts as $part) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('Now parsing part "%s"', $part)); | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |             $part      = trim($part); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // verify if correct
 | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |             $pattern   = '/[+-]\d+[wqmdy]/'; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |             $result    = preg_match($pattern, $part); | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |             if (0 === $result || false === $result) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:32:00 +01:00
										 |  |  |                 app('log')->error(sprintf('Part "%s" does not match regular expression. Will be skipped.', $part)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             $direction = str_starts_with($part, '+') ? 1 : 0; | 
					
						
							|  |  |  |             $period    = $part[strlen($part) - 1]; | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $number    = (int) substr($part, 1, -1); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             if (!array_key_exists($period, $functions[$direction])) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:32:00 +01:00
										 |  |  |                 app('log')->error(sprintf('No method for direction %d and period "%s".', $direction, $period)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-12-22 20:37:54 +01:00
										 |  |  |             $func      = $functions[$direction][$period]; | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('Will now do %s(%d) on %s', $func, $number, $today->format('Y-m-d'))); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |             $today->{$func}($number); // @phpstan-ignore-line
 | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('Resulting date is %s', $today->format('Y-m-d'))); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $today; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |     public function parseRange(string $date): array | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // several types of range can be submitted
 | 
					
						
							|  |  |  |         $result = [ | 
					
						
							|  |  |  |             'exact' => new Carbon('1984-09-17'), | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         switch (true) { | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case $this->isDayRange($date): | 
					
						
							|  |  |  |                 $result = $this->parseDayRange($date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case $this->isMonthRange($date): | 
					
						
							|  |  |  |                 $result = $this->parseMonthRange($date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case $this->isYearRange($date): | 
					
						
							|  |  |  |                 $result = $this->parseYearRange($date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case $this->isMonthDayRange($date): | 
					
						
							|  |  |  |                 $result = $this->parseMonthDayRange($date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case $this->isDayYearRange($date): | 
					
						
							|  |  |  |                 $result = $this->parseDayYearRange($date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             case $this->isMonthYearRange($date): | 
					
						
							|  |  |  |                 $result = $this->parseMonthYearRange($date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Returns true if this matches regex for xxxx-xx-DD: | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     protected function isDayRange(string $date): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-02-22 18:03:31 +01:00
										 |  |  |         $pattern = '/^xxxx-xx-(0[1-9]|[12]\d|3[01])$/'; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |         $result  = preg_match($pattern, $date); | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |         if (false !== $result && 0 !== $result) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('"%s" is a day range.', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('"%s" is not a day range.', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * format of string is xxxx-xx-DD | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function parseDayRange(string $date): array | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $parts = explode('-', $date); | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         return [ | 
					
						
							|  |  |  |             'day' => $parts[2], | 
					
						
							|  |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     protected function isMonthRange(string $date): bool | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // if regex for xxxx-MM-xx:
 | 
					
						
							|  |  |  |         $pattern = '/^xxxx-(0[1-9]|1[012])-xx$/'; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |         $result  = preg_match($pattern, $date); | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |         if (false !== $result && 0 !== $result) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('"%s" is a month range.', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('"%s" is not a month range.', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * format of string is xxxx-MM-xx | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function parseMonthRange(string $date): array | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('parseMonthRange: Parsed "%s".', $date)); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $parts = explode('-', $date); | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         return [ | 
					
						
							|  |  |  |             'month' => $parts[1], | 
					
						
							|  |  |  |         ]; | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |     protected function isYearRange(string $date): bool | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |         // if regex for YYYY-xx-xx:
 | 
					
						
							|  |  |  |         $pattern = '/^(19|20)\d\d-xx-xx$/'; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |         $result  = preg_match($pattern, $date); | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |         if (false !== $result && 0 !== $result) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('"%s" is a year range.', $date)); | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |             return true; | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('"%s" is not a year range.', $date)); | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * format of string is YYYY-xx-xx | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function parseYearRange(string $date): array | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('parseYearRange: Parsed "%s"', $date)); | 
					
						
							| 
									
										
										
										
											2021-12-17 17:27:29 +01:00
										 |  |  |         $parts = explode('-', $date); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return [ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             'year' => $parts[0], | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |         ]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function isMonthDayRange(string $date): bool | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         // if regex for xxxx-MM-DD:
 | 
					
						
							|  |  |  |         $pattern = '/^xxxx-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/'; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |         $result  = preg_match($pattern, $date); | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |         if (false !== $result && 0 !== $result) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('"%s" is a month/day range.', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('"%s" is not a month/day range.', $date)); | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * format of string is xxxx-MM-DD | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function parseMonthDayRange(string $date): array | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         app('log')->debug(sprintf('parseMonthDayRange: Parsed "%s".', $date)); | 
					
						
							|  |  |  |         $parts = explode('-', $date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return [ | 
					
						
							|  |  |  |             'month' => $parts[1], | 
					
						
							|  |  |  |             'day'   => $parts[2], | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function isDayYearRange(string $date): bool | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         // if regex for YYYY-xx-DD:
 | 
					
						
							|  |  |  |         $pattern = '/^(19|20)\d\d-xx-(0[1-9]|[12]\d|3[01])$/'; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |         $result  = preg_match($pattern, $date); | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |         if (false !== $result && 0 !== $result) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('"%s" is a day/year range.', $date)); | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             return true; | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('"%s" is not a day/year range.', $date)); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-22 20:11:09 +01:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * format of string is YYYY-xx-DD | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     private function parseDayYearRange(string $date): array | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         app('log')->debug(sprintf('parseDayYearRange: Parsed "%s".', $date)); | 
					
						
							|  |  |  |         $parts = explode('-', $date); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return [ | 
					
						
							|  |  |  |             'year' => $parts[0], | 
					
						
							|  |  |  |             'day'  => $parts[2], | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function isMonthYearRange(string $date): bool | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         // if regex for YYYY-MM-xx:
 | 
					
						
							|  |  |  |         $pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-xx$/'; | 
					
						
							| 
									
										
										
										
											2025-05-27 17:06:15 +02:00
										 |  |  |         $result  = preg_match($pattern, $date); | 
					
						
							| 
									
										
										
										
											2023-12-21 05:06:51 +01:00
										 |  |  |         if (false !== $result && 0 !== $result) { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |             app('log')->debug(sprintf('"%s" is a month/year range.', $date)); | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('"%s" is not a month/year range.', $date)); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2021-09-18 10:26:12 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * format of string is YYYY-MM-xx | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function parseMonthYearRange(string $date): array | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-29 06:33:43 +01:00
										 |  |  |         app('log')->debug(sprintf('parseMonthYearRange: Parsed "%s".', $date)); | 
					
						
							| 
									
										
										
										
											2021-12-17 17:27:29 +01:00
										 |  |  |         $parts = explode('-', $date); | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return [ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             'year'  => $parts[0], | 
					
						
							| 
									
										
										
										
											2021-12-17 17:27:29 +01:00
										 |  |  |             'month' => $parts[1], | 
					
						
							| 
									
										
										
										
											2020-06-12 07:49:39 +02:00
										 |  |  |         ]; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-05-16 12:11:06 +02:00
										 |  |  | } |