1414namespace Ixnode \PhpDateParser \Base ;
1515
1616use DateTime ;
17+ use DateTimeImmutable ;
18+ use DateTimeZone ;
1719use Exception ;
1820use Ixnode \PhpDateParser \DateRange ;
21+ use Ixnode \PhpException \Case \CaseUnsupportedException ;
1922use Ixnode \PhpException \Parser \ParserException ;
2023use Ixnode \PhpException \Type \TypeInvalidException ;
2124
@@ -52,6 +55,8 @@ class BaseDateParser
5255
5356 final public const FORMAT_THIS_YEAR_LAST = 'Y-12-31 ' ;
5457
58+ final public const VALUE_NOW = 'now ' ;
59+
5560 final public const VALUE_TOMORROW = 'tomorrow ' ;
5661
5762 final public const VALUE_TODAY = 'today ' ;
@@ -78,10 +83,11 @@ class BaseDateParser
7883
7984 /**
8085 * @param string|null $range
81- * @throws TypeInvalidException
86+ * @param DateTimeZone $dateTimeZoneInput
8287 * @throws ParserException
88+ * @throws TypeInvalidException
8389 */
84- public function __construct (string |null $ range )
90+ public function __construct (string |null $ range, protected DateTimeZone $ dateTimeZoneInput = new DateTimeZone ( ' UTC ' ) )
8591 {
8692 $ this ->range = !is_null ($ range ) ? trim (strtolower ($ range )) : null ;
8793
@@ -102,7 +108,7 @@ public function __construct(string|null $range)
102108 private function parseRange (string |null $ range ): DateRange
103109 {
104110 if (is_null ($ range )) {
105- return new DateRange (
111+ return $ this -> getDateRangeInstance (
106112 null ,
107113 null
108114 );
@@ -114,30 +120,30 @@ private function parseRange(string|null $range): DateRange
114120
115121 /* Parses "tomorrow" date. */
116122 case $ range === self ::VALUE_TOMORROW :
117- return new DateRange (
118- ( new DateTime ( self ::VALUE_TOMORROW ))-> setTime ( self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
119- ( new DateTime ( self ::VALUE_TOMORROW ))-> setTime ( self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
123+ return $ this -> getDateRangeInstance (
124+ $ this -> getDateTimeRaw ( self ::VALUE_TOMORROW , self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
125+ $ this -> getDateTimeRaw ( self ::VALUE_TOMORROW , self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
120126 );
121127 /* Parses "today" date. */
122128 case $ range === self ::VALUE_TODAY :
123- return new DateRange (
124- ( new DateTime ())-> setTime ( self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
125- ( new DateTime ())-> setTime ( self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
129+ return $ this -> getDateRangeInstance (
130+ $ this -> getDateTimeRaw ( self :: VALUE_NOW , self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
131+ $ this -> getDateTimeRaw ( self :: VALUE_NOW , self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
126132 );
127133 /* Parses "yesterday" date. */
128134 case $ range === self ::VALUE_YESTERDAY :
129- return new DateRange (
130- ( new DateTime ( self ::VALUE_YESTERDAY ))-> setTime ( self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
131- ( new DateTime ( self ::VALUE_YESTERDAY ))-> setTime ( self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
135+ return $ this -> getDateRangeInstance (
136+ $ this -> getDateTimeRaw ( self ::VALUE_YESTERDAY , self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
137+ $ this -> getDateTimeRaw ( self ::VALUE_YESTERDAY , self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
132138 );
133139 /* Parses "next-month" date. */
134140 case $ range === self ::VALUE_NEXT_MONTH :
135141 return $ this ->getDateRangeNextMonth ();
136142 /* Parses "this-month" date. */
137143 case $ range === self ::VALUE_THIS_MONTH :
138- return new DateRange (
139- ( new DateTime ( date (self ::FORMAT_THIS_MONTH_FIRST )))-> setTime ( self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
140- ( new DateTime ( date (self ::FORMAT_THIS_MONTH_LAST )))-> setTime ( self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
144+ return $ this -> getDateRangeInstance (
145+ $ this -> getDateTimeRaw ( date (self ::FORMAT_THIS_MONTH_FIRST ), self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
146+ $ this -> getDateTimeRaw ( date (self ::FORMAT_THIS_MONTH_LAST ), self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
141147 );
142148 /* Parses "last-month" date. */
143149 case $ range === self ::VALUE_LAST_MONTH :
@@ -147,9 +153,9 @@ private function parseRange(string|null $range): DateRange
147153 return $ this ->getDateRangeNextYear ();
148154 /* Parses "this-year" date. */
149155 case $ range === self ::VALUE_THIS_YEAR :
150- return new DateRange (
151- ( new DateTime ( date (self ::FORMAT_THIS_YEAR_FIRST )))-> setTime ( self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
152- ( new DateTime ( date (self ::FORMAT_THIS_YEAR_LAST )))-> setTime ( self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
156+ return $ this -> getDateRangeInstance (
157+ $ this -> getDateTimeRaw ( date (self ::FORMAT_THIS_YEAR_FIRST ), self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
158+ $ this -> getDateTimeRaw ( date (self ::FORMAT_THIS_YEAR_LAST ), self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST )
153159 );
154160 /* Parses "last-year" date. */
155161 case $ range === self ::VALUE_LAST_YEAR :
@@ -158,13 +164,13 @@ private function parseRange(string|null $range): DateRange
158164
159165 /* Starts with <+: parses a "∞ (infinity)" to given "from" date (including given date). */
160166 case preg_match ('~^(<[+=]|-)~ ' , $ range , $ matches ) === 1 :
161- return new DateRange (
167+ return $ this -> getDateRangeInstance (
162168 null ,
163169 $ this ->parseRange (substr ($ range , strlen ($ matches [1 ])))->getTo ()
164170 );
165171 /* Starts with <: parses a "∞ (infinity)" to given "from" date (excluding given date). */
166172 case str_starts_with ($ range , '< ' ):
167- return new DateRange (
173+ return $ this -> getDateRangeInstance (
168174 null ,
169175 $ this ->parseRange (substr ($ range , 1 ))
170176 ->getTo ()
@@ -174,13 +180,13 @@ private function parseRange(string|null $range): DateRange
174180
175181 /* Starts with >+: parses a given "from" (including given date) to "∞ (infinity)" date. */
176182 case preg_match ('~^(>[+=]|[+])~ ' , $ range , $ matches ) === 1 :
177- return new DateRange (
183+ return $ this -> getDateRangeInstance (
178184 $ this ->parseRange (substr ($ range , strlen ($ matches [1 ])))->getFrom (),
179185 null
180186 );
181187 /* Starts with >: parses a given "from" (excluding given date) to "∞ (infinity)" date. */
182188 case str_starts_with ($ range , '> ' ):
183- return new DateRange (
189+ return $ this -> getDateRangeInstance (
184190 $ this ->parseRange (substr ($ range , 1 ))->getTo ()?->modify('+1 second ' ),
185191 null
186192 );
@@ -189,23 +195,23 @@ private function parseRange(string|null $range): DateRange
189195 /* Starts with |: parses a given "from" (including given date) to "to" date (including given date). */
190196 case str_contains ($ range , '| ' ):
191197 $ splitted = explode ('| ' , $ range );
192- return new DateRange (
198+ return $ this -> getDateRangeInstance (
193199 $ this ->parseRange ($ splitted [0 ])->getFrom (),
194200 $ this ->parseRange ($ splitted [1 ])->getTo ()
195201 );
196202
197203
198204 /* Starts with =: a given date exactly. */
199205 case str_starts_with ($ range , '= ' ):
200- return new DateRange (
206+ return $ this -> getDateRangeInstance (
201207 $ this ->parseRange (substr ($ range , 1 ))->getFrom (),
202208 $ this ->parseRange (substr ($ range , 1 ))->getTo (),
203209 );
204210
205211
206212 /* Parse the date */
207213 default :
208- return new DateRange (
214+ return $ this -> getDateRangeInstance (
209215 $ this ->parseDate ($ range )->setTime (self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST ),
210216 $ this ->parseDate ($ range )->setTime (self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST ),
211217 );
@@ -227,7 +233,7 @@ private function getDateRangeNextMonth(): DateRange
227233 $ lastNextMonth = (new DateTime ($ firstNextMonth ->format (self ::FORMAT_THIS_MONTH_LAST )))
228234 ->setTime (self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST );
229235
230- return new DateRange ($ firstNextMonth , $ lastNextMonth );
236+ return $ this -> getDateRangeInstance ($ firstNextMonth , $ lastNextMonth );
231237 }
232238
233239 /**
@@ -246,7 +252,7 @@ private function getDateRangeLastMonth(): DateRange
246252 $ firstLastMonth = (new DateTime ($ lastLastMonth ->format (self ::FORMAT_THIS_MONTH_FIRST )))
247253 ->setTime (self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST );
248254
249- return new DateRange ($ firstLastMonth , $ lastLastMonth );
255+ return $ this -> getDateRangeInstance ($ firstLastMonth , $ lastLastMonth );
250256 }
251257
252258 /**
@@ -264,7 +270,7 @@ private function getDateRangeNextYear(): DateRange
264270 $ lastNextYear = (new DateTime ($ firstNextYear ->format (self ::FORMAT_THIS_YEAR_LAST )))
265271 ->setTime (self ::HOUR_LAST , self ::MINUTE_LAST , self ::SECOND_LAST );
266272
267- return new DateRange ($ firstNextYear , $ lastNextYear );
273+ return $ this -> getDateRangeInstance ($ firstNextYear , $ lastNextYear );
268274 }
269275
270276 /**
@@ -283,7 +289,7 @@ private function getDateRangeLastYear(): DateRange
283289 $ firstLastYear = (new DateTime ($ lastLastYear ->format (self ::FORMAT_THIS_YEAR_FIRST )))
284290 ->setTime (self ::HOUR_FIRST , self ::MINUTE_FIRST , self ::SECOND_FIRST );
285291
286- return new DateRange ($ firstLastYear , $ lastLastYear );
292+ return $ this -> getDateRangeInstance ($ firstLastYear , $ lastLastYear );
287293 }
288294
289295 /**
@@ -308,4 +314,31 @@ protected function parseDate(string $date): DateTime
308314
309315 return $ date ;
310316 }
317+
318+ /**
319+ * @param string $dateTime
320+ * @param int $hour
321+ * @param int $minute
322+ * @param int $second
323+ * @return DateTime
324+ * @throws Exception
325+ */
326+ protected function getDateTimeRaw (string $ dateTime , int $ hour , int $ minute , int $ second ): DateTime
327+ {
328+ return (new DateTime ($ dateTime ))->setTime ($ hour , $ minute , $ second );
329+ }
330+
331+ /**
332+ * Returns the DateRange instance from given date range.
333+ *
334+ * @param DateTime|DateTimeImmutable|null $from
335+ * @param DateTime|DateTimeImmutable|null $to
336+ * @return DateRange
337+ * @throws CaseUnsupportedException
338+ * @SuppressWarnings(PHPMD.ShortVariable)
339+ */
340+ protected function getDateRangeInstance (DateTime |DateTimeImmutable |null $ from , DateTime |DateTimeImmutable |null $ to ): DateRange
341+ {
342+ return new DateRange ($ from , $ to , $ this ->dateTimeZoneInput );
343+ }
311344}
0 commit comments