diff --git a/src/Forms/DateField.php b/src/Forms/DateField.php index 880fa0827..83a695c4b 100644 --- a/src/Forms/DateField.php +++ b/src/Forms/DateField.php @@ -513,8 +513,8 @@ class DateField extends TextField * Convert frontend date to the internal representation (ISO 8601). * The frontend date is also in ISO 8601 when $html5=true. * - * @param string $date - * @return string The formatted date, or null if not a valid date + * @param ?string $date + * @return ?string The formatted date, or null if not a valid date */ protected function frontendToInternal($date) { @@ -524,6 +524,17 @@ class DateField extends TextField $fromFormatter = $this->getFrontendFormatter(); $toFormatter = $this->getInternalFormatter(); $timestamp = $fromFormatter->parse($date); + + // Retry with expanded value + if ($timestamp === false) { + $zeroFormat = $fromFormatter->format(strtotime(date('Y-01-01 00:00:00'))); + $expectedLength = strlen($zeroFormat); + if (strlen($date) < $expectedLength) { + $expandedValue = $date . substr($zeroFormat, strlen($date)); + $timestamp = $fromFormatter->parse($expandedValue); + } + } + if ($timestamp === false) { return null; } diff --git a/src/Forms/DatetimeField.php b/src/Forms/DatetimeField.php index 849a0ecb8..2a52f1bfc 100644 --- a/src/Forms/DatetimeField.php +++ b/src/Forms/DatetimeField.php @@ -179,8 +179,8 @@ class DatetimeField extends TextField * Assumes the value is in the defined {@link $timezone} (if one is set), * and adjusts for server timezone. * - * @param string $datetime - * @return string The formatted date, or null if not a valid date + * @param ?string $datetime + * @return ?string The formatted date, or null if not a valid date */ public function frontendToInternal($datetime) { @@ -193,6 +193,16 @@ class DatetimeField extends TextField // Try to parse time with seconds $timestamp = $fromFormatter->parse($datetime); + // Retry with expanded value + if ($timestamp === false) { + $zeroFormat = $fromFormatter->format(strtotime(date('Y-01-01 00:00:00'))); + $expectedLength = strlen($zeroFormat); + if (strlen($datetime) < $expectedLength) { + $expandedValue = $datetime . substr($zeroFormat, strlen($datetime)); + $timestamp = $fromFormatter->parse($expandedValue); + } + } + // Try to parse time without seconds, since that's a valid HTML5 submission format // See https://html.spec.whatwg.org/multipage/infrastructure.html#times if ($timestamp === false && $this->getHTML5()) { diff --git a/src/Forms/TimeField.php b/src/Forms/TimeField.php index 24ba4645f..41d86c65f 100644 --- a/src/Forms/TimeField.php +++ b/src/Forms/TimeField.php @@ -388,8 +388,8 @@ class TimeField extends TextField * Convert frontend time to the internal representation (ISO 8601). * The frontend time is also in ISO 8601 when $html5=true. * - * @param string $time - * @return string The formatted time, or null if not a valid time + * @param ?string $time + * @return ?string The formatted time, or null if not a valid time */ protected function frontendToInternal($time) { @@ -400,6 +400,16 @@ class TimeField extends TextField $toFormatter = $this->getInternalFormatter(); $timestamp = $fromFormatter->parse($time); + // Retry with expanded value + if ($timestamp === false) { + $zeroFormat = $fromFormatter->format(strtotime(date('Y-01-01 00:00:00'))); + $expectedLength = strlen($zeroFormat); + if (strlen($time) < $expectedLength) { + $expandedValue = $time . substr($zeroFormat, strlen($time)); + $timestamp = $fromFormatter->parse($expandedValue); + } + } + // Try to parse time without seconds, since that's a valid HTML5 submission format // See https://html.spec.whatwg.org/multipage/infrastructure.html#times if ($timestamp === false && $this->getHTML5()) {