55namespace KaririCode \Transformer \Processor \Data ;
66
77use KaririCode \Contract \Processor \ConfigurableProcessor ;
8+ use KaririCode \Transformer \Exception \DateTransformerException ;
89use KaririCode \Transformer \Processor \AbstractTransformerProcessor ;
910
10- class DateTransformer extends AbstractTransformerProcessor implements ConfigurableProcessor
11+ final class DateTransformer extends AbstractTransformerProcessor implements ConfigurableProcessor
1112{
12- private string $ inputFormat = 'Y-m-d ' ;
13- private string $ outputFormat = 'Y-m-d ' ;
14- private ?string $ inputTimezone = null ;
15- private ?string $ outputTimezone = null ;
13+ private const DEFAULT_FORMAT = 'Y-m-d ' ;
14+ private const ERROR_INVALID_STRING = 'notString ' ;
15+ private const ERROR_INVALID_DATE = 'invalidDate ' ;
16+
17+ private string $ inputFormat = self ::DEFAULT_FORMAT ;
18+ private string $ outputFormat = self ::DEFAULT_FORMAT ;
19+ private ?\DateTimeZone $ inputTimezone = null ;
20+ private ?\DateTimeZone $ outputTimezone = null ;
1621
1722 public function configure (array $ options ): void
1823 {
19- $ this ->inputFormat = $ options ['inputFormat ' ] ?? $ this ->inputFormat ;
20- $ this ->outputFormat = $ options ['outputFormat ' ] ?? $ this ->outputFormat ;
21- $ this ->inputTimezone = $ options ['inputTimezone ' ] ?? $ this ->inputTimezone ;
22- $ this ->outputTimezone = $ options ['outputTimezone ' ] ?? $ this ->outputTimezone ;
24+ $ this ->configureFormats ($ options );
25+ $ this ->configureTimezones ($ options );
2326 }
2427
2528 public function process (mixed $ input ): string
2629 {
27- if (!is_string ($ input )) {
28- $ this ->setInvalid ('notString ' );
29-
30+ if (!$ this ->isValidInput ($ input )) {
3031 return '' ;
3132 }
3233
3334 try {
34- $ date = $ this ->createDateTime ($ input );
35-
36- return $ this ->formatDate ($ date );
37- } catch (\Exception $ e ) {
38- $ this ->setInvalid ('invalidDate ' );
35+ return $ this ->transformDate ($ input );
36+ } catch (DateTransformerException ) {
37+ $ this ->setInvalid (self ::ERROR_INVALID_DATE );
3938
4039 return '' ;
4140 }
4241 }
4342
44- private function createDateTime (string $ input ): \DateTime
43+ private function configureFormats (array $ options ): void
44+ {
45+ $ this ->inputFormat = $ options ['inputFormat ' ] ?? self ::DEFAULT_FORMAT ;
46+ $ this ->outputFormat = $ options ['outputFormat ' ] ?? self ::DEFAULT_FORMAT ;
47+ }
48+
49+ private function configureTimezones (array $ options ): void
4550 {
46- $ date = \DateTime::createFromFormat ($ this ->inputFormat , $ input );
51+ $ this ->inputTimezone = $ this ->createTimezone ($ options ['inputTimezone ' ] ?? null );
52+ $ this ->outputTimezone = $ this ->createTimezone ($ options ['outputTimezone ' ] ?? null );
53+ }
54+
55+ private function createTimezone (?string $ timezone ): ?\DateTimeZone
56+ {
57+ if (!$ timezone ) {
58+ return null ;
59+ }
60+
61+ try {
62+ return new \DateTimeZone ($ timezone );
63+ } catch (\Exception ) {
64+ throw DateTransformerException::invalidTimezone ($ timezone );
65+ }
66+ }
4767
48- if (false === $ date ) {
49- throw new \RuntimeException ('Invalid date format ' );
68+ private function isValidInput (mixed $ input ): bool
69+ {
70+ if (is_string ($ input )) {
71+ return true ;
5072 }
5173
52- if ($ this ->inputTimezone ) {
53- $ date ->setTimezone (new \DateTimeZone ($ this ->inputTimezone ));
74+ $ this ->setInvalid (self ::ERROR_INVALID_STRING );
75+
76+ return false ;
77+ }
78+
79+ private function transformDate (string $ input ): string
80+ {
81+ $ date = $ this ->createDateTime ($ input );
82+
83+ return $ this ->formatDate ($ date );
84+ }
85+
86+ private function createDateTime (string $ input ): \DateTime
87+ {
88+ $ date = \DateTime::createFromFormat ($ this ->inputFormat , $ input , $ this ->inputTimezone );
89+
90+ if (!$ date ) {
91+ throw DateTransformerException::invalidFormat ($ this ->inputFormat , $ input );
5492 }
5593
5694 return $ date ;
@@ -59,7 +97,11 @@ private function createDateTime(string $input): \DateTime
5997 private function formatDate (\DateTime $ date ): string
6098 {
6199 if ($ this ->outputTimezone ) {
62- $ date ->setTimezone (new \DateTimeZone ($ this ->outputTimezone ));
100+ try {
101+ $ date ->setTimezone ($ this ->outputTimezone );
102+ } catch (\Exception ) {
103+ throw DateTransformerException::invalidDate ($ date ->format ('Y-m-d H:i:s ' ));
104+ }
63105 }
64106
65107 return $ date ->format ($ this ->outputFormat );
0 commit comments