parseTime static method
Reads a clock time — a time node's bound, and its stored value.
DateTime.tryParse('09:00') returns null. The server publishes a
time bound exactly as the panel declared it (getMinDate() is
evaluate($this->minDate) and nothing more, measured in vendor), so
"09:00" is the ordinary case — and reading it with the date parse
would silently delete a bound the panel really set, then offer the user
times the server rejects, through the very path written to be safe.
A panel that declared its bound as a Carbon publishes
"2026-01-01 09:00:00" instead, which DateTime.tryParse does read.
Only the clock reading is meaningful for a time field, so both shapes
normalise onto one comparable value.
Public because the renderer parses a stored "14:05:00" the same way it
parses a bound; one parser, so the two cannot drift.
Implementation
static DateTime? parseTime(String raw) {
final full = DateTime.tryParse(raw);
if (full != null) return timeOfDay(full.hour, full.minute, full.second);
final match = _clockTime.firstMatch(raw.trim());
if (match == null) return null;
final hour = int.parse(match[1]!);
final minute = int.parse(match[2]!);
final second = int.parse(match[3] ?? '0');
// `DateTime.utc(1970, 1, 1, 25)` is a perfectly valid DateTime — 01:00
// the next day — so without this check a nonsense bound would arrive as a
// plausible one.
if (hour > 23 || minute > 59 || second > 59) return null;
return timeOfDay(hour, minute, second);
}