/*
Program goal:
-------------
Sort a list of date strings in the format "YYYY-MM-DD".
Approach:
1. Parse each string into a Date object using a safe, explicit parser.
2. Sort using Array.prototype.sort() with a comparator.
3. Convert back to strings and print results.
Architecture notes:
-------------------
- Parsing is isolated in a dedicated function for clarity and testability.
- Sorting uses the built-in sort() with a comparator (O(n log n)).
- Error handling: invalid formats are detected and reported.
- Edge cases: malformed strings, invalid ranges, leap years.
- Performance: Date parsing is fast; sorting is O(n log n).
- Memory: minimal; only an array of small objects.
- Security: no unsafe operations; avoids eval-like parsing.
*/
/*
Parse a date string into a Date object.
Throws an error with a clear message on failure.
*/
function parseDate(s) {
// Basic structural validation: YYYY-MM-DD
if (!/^\d{4}-\d{2}-\d{2}$/.test(s)) {
throw new Error("Invalid date format: " + s);
}
const [year, month, day] = s.split("-").map(Number);
// Construct a Date in UTC to avoid timezone surprises
const dt = new Date(Date.UTC(year, month - 1, day));
// Validate that the Date object matches the input (detects invalid calendar dates)
if (
dt.getUTCFullYear() !== year ||
dt.getUTCMonth() !== month - 1 ||
dt.getUTCDate() !== day
) {
throw new Error("Invalid calendar date: " + s);
}
return dt;
}
/*
Sort a list of date strings.
Returns a new sorted array; does not mutate the input.
*/
function sortDates(dates) {
const parsed = [];
// Parse all dates; fail fast on invalid input.
for (const s of dates) {
parsed.push(parseDate(s));
}
// Sort using natural Date ordering.
parsed.sort((a, b) => a - b);
// Convert back to strings.
return parsed.map(
d =>
`${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, "0")}-${String(
d.getUTCDate()
).padStart(2, "0")}`
);
}
/*
Helper to print a list of strings.
*/
function printList(list) {
for (const s of list) {
console.log(" " + s);
}
}
/*
Helper to run a named test case.
*/
function runTest(name, dates) {
console.log("\n=== " + name + " ===");
try {
const sorted = sortDates(dates);
printList(sorted);
} catch (e) {
console.log("Error: " + e.message);
}
}
/*
Main program with multiple test cases.
*/
console.log("JavaScript Date Sorting Demo");
/* 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:
JavaScript 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!
Error: Invalid calendar date: 2024-13-01
*/