@@ -62,7 +62,18 @@ function {{functionName}}(array {{jsonPath}}): {{className}}
6262EOT;
6363
6464 private const TMPL_ASSIGN_DATETIME_FROM_FORMAT = <<<'EOT'
65- {{modelPath}} = \DateTime::createFromFormat('{{format}}', {{jsonPath}});
65+ {{date}} = false;
66+ foreach([{{formats|join(', ')}}] as {{format}}) {
67+ if (({{date}} = \DateTime::createFromFormat({{format}}, {{jsonPath}}, {{timezone}}))) {
68+ {{modelPath}} = {{date}};
69+ break;
70+ }
71+ }
72+
73+ if (false === {{date}}) {
74+ throw new \Exception('Invalid datetime string '.({{jsonPath}}).' matches none of the deserialization formats: '.{{formatsError}});
75+ }
76+ unset({{format}}, {{date}});
6677
6778EOT;
6879
@@ -72,7 +83,18 @@ function {{functionName}}(array {{jsonPath}}): {{className}}
7283EOT;
7384
7485 private const TMPL_ASSIGN_DATETIME_IMMUTABLE_FROM_FORMAT = <<<'EOT'
75- {{modelPath}} = \DateTimeImmutable::createFromFormat('{{format}}', {{jsonPath}});
86+ {{date}} = false;
87+ foreach([{{formats|join(', ')}}] as {{format}}) {
88+ if (({{date}} = \DateTimeImmutable::createFromFormat({{format}}, {{jsonPath}}, {{timezone}}))) {
89+ {{modelPath}} = {{date}};
90+ break;
91+ }
92+ }
93+
94+ if (false === {{date}}) {
95+ throw new \Exception('Invalid datetime string '.({{jsonPath}}).' matches none of the deserialization formats: '.{{formatsError}});
96+ }
97+ unset({{format}}, {{date}});
7698
7799EOT;
78100
@@ -190,14 +212,36 @@ public function renderAssignDateTimeToField(bool $immutable, string $modelPath,
190212 ]);
191213 }
192214
193- public function renderAssignDateTimeFromFormat (bool $ immutable , string $ modelPath , string $ jsonPath , string $ format ): string
215+ /**
216+ * @param list<string>|string $formats
217+ */
218+ public function renderAssignDateTimeFromFormat (bool $ immutable , string $ modelPath , string $ jsonPath , array |string $ formats , string $ timezone = null ): string
194219 {
220+ if (\is_string ($ formats )) {
221+ @trigger_error ('Passing a string for argument $formats is deprecated, please pass an array of strings instead ' , \E_USER_DEPRECATED );
222+ $ formats = [$ formats ];
223+ }
224+
195225 $ template = $ immutable ? self ::TMPL_ASSIGN_DATETIME_IMMUTABLE_FROM_FORMAT : self ::TMPL_ASSIGN_DATETIME_FROM_FORMAT ;
226+ $ formats = array_map (
227+ static fn (string $ f ): string => var_export ($ f , true ),
228+ $ formats
229+ );
230+ $ formatsError = var_export (implode (', ' , $ formats ), true );
231+ $ dateVariable = preg_replace_callback (
232+ '/([^a-zA-Z]+|\d+)([a-zA-Z])/ ' ,
233+ static fn ($ match ): string => (ctype_digit ($ match [1 ]) ? $ match [1 ] : null ).mb_strtoupper ($ match [2 ]),
234+ $ modelPath
235+ );
196236
197237 return $ this ->render ($ template , [
198238 'modelPath ' => $ modelPath ,
199239 'jsonPath ' => $ jsonPath ,
200- 'format ' => $ format ,
240+ 'formats ' => $ formats ,
241+ 'formatsError ' => $ formatsError ,
242+ 'format ' => '$ ' .lcfirst ($ dateVariable ).'Format ' ,
243+ 'date ' => '$ ' .lcfirst ($ dateVariable ),
244+ 'timezone ' => $ timezone ? 'new \DateTimeZone( ' .var_export ($ timezone , true ).') ' : 'null ' ,
201245 ]);
202246 }
203247
0 commit comments