@@ -238,6 +238,26 @@ function convertTimeFormat($time) {
238238 }
239239}
240240
241+ /**
242+ * Normalize an ordinal date to YYYY-MM-DD
243+ * This function should only be called after validating the $dtValue
244+ * matches regex \d{4}-\d{2}
245+ * @param string $dtValue
246+ * @return string
247+ */
248+ function normalizeOrdinalDate ($ dtValue ) {
249+ list ($ year , $ day ) = explode ('- ' , $ dtValue , 2 );
250+ $ day = intval ($ day );
251+ if ($ day < 367 && $ day > 0 ) {
252+ $ date = \DateTime::createFromFormat ('Y-z ' , $ dtValue );
253+ $ date ->modify ('-1 day ' ); # 'z' format is zero-based so need to adjust
254+ if ($ date ->format ('Y ' ) === $ year ) {
255+ return $ date ->format ('Y-m-d ' );
256+ }
257+ }
258+ return '' ;
259+ }
260+
241261/**
242262 * If a date value has a timezone offset, normalize it.
243263 * @param string $dtValue
@@ -711,6 +731,9 @@ public function parseDT(\DOMElement $dt, &$dates = array(), &$impliedTimezone =
711731 // Is the current part a valid date AND no other date representation has been found?
712732 } elseif (preg_match ('/^\d{4}-\d{2}-\d{2}$/ ' , $ part ) and empty ($ datePart )) {
713733 $ datePart = $ part ;
734+ // Is the current part a valid ordinal date AND no other date representation has been found?
735+ } elseif (preg_match ('/^\d{4}-\d{3}$/ ' , $ part ) and empty ($ datePart )) {
736+ $ datePart = normalizeOrdinalDate ($ part );
714737 // Is the current part a valid timezone offset AND no other timezone part has been found?
715738 } elseif (preg_match ('/^(Z|[+-]\d{1,2}:?(\d{2})?)$/ ' , $ part ) and empty ($ timezonePart )) {
716739 $ timezonePart = $ part ;
0 commit comments