/*
Program goal:
-------------
Sort a list of date strings in the format "YYYY-MM-DD".
Approach:
1. Parse each string into DateTime using DateTime::createFromFormat.
2. Sort using usort() with a comparator that compares DateTime objects.
3. Print results.
Architecture notes:
-------------------
- Parsing is isolated in a dedicated function for clarity and testability.
- Sorting uses usort(), which is efficient (O(n log n)).
- Error handling: invalid formats are detected and reported.
- Edge cases: malformed strings, invalid ranges, leap years.
- Performance: DateTime parsing is fast; sorting is O(n log n).
- Memory: minimal; only an array of small objects.
- Security: no unsafe operations; uses immutable DateTime.
*/
/*
Parse a date string into a DateTime object.
Returns the DateTime or throws an exception with a clear message.
*/
function parseDate(string $s): DateTime {
$dt = DateTime::createFromFormat('Y-m-d', $s);
$errors = DateTime::getLastErrors();
// If parsing failed OR errors array exists and contains warnings/errors
if ($dt === false ||
(is_array($errors) &&
($errors['warning_count'] > 0 || $errors['error_count'] > 0))) {
throw new InvalidArgumentException("Invalid date: $s");
}
return $dt;
}
/*
Sort a list of date strings.
Returns a new sorted array; does not mutate the input.
*/
function sortDates(array $dates): array {
$parsed = [];
// Parse all dates; fail fast on invalid input.
foreach ($dates as $s) {
$parsed[] = parseDate($s);
}
// Sort using natural DateTime ordering.
usort($parsed, function(DateTime $a, DateTime $b) {
return $a <=> $b;
});
// Convert back to strings.
$result = [];
foreach ($parsed as $d) {
$result[] = $d->format('Y-m-d');
}
return $result;
}
/*
Helper to print a list of strings.
*/
function printList(array $list): void {
foreach ($list as $s) {
echo " $s\n";
}
}
/*
Helper to run a named test case.
*/
function runTest(string $name, array $dates): void {
echo "\n=== $name ===\n";
try {
$sorted = sortDates($dates);
printList($sorted);
} catch (Exception $e) {
echo "Error: {$e->getMessage()}\n";
}
}
/*
Main program with multiple test cases.
*/
echo "PHP Date Sorting Demo\n";
/* Basic chronological order */
runTest("Basic chronological order", [
"2024-01-05",
"2023-12-31",
"2024-01-01",
"2022-07-15"
]);
/* Already sorted input */
runTest("Already sorted input", [
"2020-01-01",
"2020-01-02",
"2020-01-03"
]);
/* Leap year edge cases */
runTest("Leap year edge cases", [
"2020-02-29",
"2019-02-28",
"2021-03-01"
]);
/* Invalid date detection */
runTest("Invalid date detection", [
"2024-13-01", // invalid month
"2024-02-30", // invalid day
"not-a-date" // malformed
]);
/*
run:
ERROR!
PHP Date Sorting Demo
=== Basic chronological order ===
2022-07-15
2023-12-31
2024-01-01
2024-01-05
=== Already sorted input ===
2020-01-01
2020-01-02
2020-01-03
=== Leap year edge cases ===
2019-02-28
2020-02-29
2021-03-01
=== Invalid date detection ===
Error: Invalid date: 2024-13-01
*/