import Foundation
/*
Program goal:
-------------
Sort a list of date strings in the format "YYYY-MM-DD".
Approach:
1. Parse each string into Date using a strict DateFormatter.
2. Sort using Swift’s built-in sorted(by:) (O(n log n)).
3. Convert back to strings and print results.
Architecture notes:
-------------------
- Parsing is isolated in a dedicated function for clarity and testability.
- Sorting uses sorted(by:), which is efficient and stable.
- 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: avoids unsafe operations; uses immutable Date values.
*/
// Custom error type for date parsing
enum DateParseError: Error {
case invalidDate(String)
var message: String {
switch self {
case .invalidDate(let s):
return "Invalid date: \(s)"
}
}
}
// Strict ISO 8601 formatter
let isoFormatter: DateFormatter = {
let f = DateFormatter()
f.dateFormat = "yyyy-MM-dd"
f.locale = Locale(identifier: "en_US_POSIX") // stable parsing
f.timeZone = TimeZone(secondsFromGMT: 0) // avoid timezone shifts
return f
}()
/*
Parse a date string into Date.
Returns Result<Date, DateParseError> for safe error handling.
*/
func parseDate(_ s: String) -> Result<Date, DateParseError> {
if let dt = isoFormatter.date(from: s) {
return .success(dt)
} else {
return .failure(.invalidDate(s))
}
}
/*
Sort a list of date strings.
Returns Result<[String], DateParseError> to propagate errors.
*/
func sortDates(_ dates: [String]) -> Result<[String], DateParseError> {
var parsed: [Date] = []
// Parse all dates; fail fast on invalid input.
for s in dates {
switch parseDate(s) {
case .success(let dt):
parsed.append(dt)
case .failure(let err):
return .failure(err)
}
}
// Sort using natural Date ordering.
let sorted = parsed.sorted()
// Convert back to strings.
let result = sorted.map { isoFormatter.string(from: $0) }
return .success(result)
}
/*
Helper to print a list of strings.
*/
func printList(_ list: [String]) {
for s in list {
print(" \(s)")
}
}
/*
Helper to run a named test case.
*/
func runTest(_ name: String, _ dates: [String]) {
print("\n=== \(name) ===")
switch sortDates(dates) {
case .success(let sorted):
printList(sorted)
case .failure(let err):
print("Error: \(err.message)")
}
}
/*
Main program with multiple test cases.
*/
print("Swift 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", "2024-02-30", "not-a-date"])
/*
run:
Swift 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 date: 2024-13-01
*/