import Foundation
/*
Compare two dates in Swift
--------------------------
This program demonstrates how to compare two dates using Swift’s built‑in
Foundation date/time APIs. It uses a modular design, clear comments, and a full
test suite.
Concepts:
- Parsing dates safely (YYYY‑MM‑DD)
- Comparing Date objects
- Handling invalid formats
- Edge‑case testing
Architecture notes:
- A dedicated function handles parsing.
- Another function performs comparison.
- Main runs multiple predefined test cases.
- No external dependencies; only standard library.
Performance notes:
- Date comparisons are O(1).
- Parsing is fast and predictable.
- Memory usage is minimal.
Pitfalls:
- Invalid date strings must be handled.
- Comparing raw strings is unsafe; always convert to Date.
- Date includes time and timezone; here we normalize to midnight UTC.
*/
/*
Safely parse a date string in the format YYYY-MM-DD.
Error handling:
- Returns nil if the date is invalid.
*/
func parseDate(_ s: String) -> Date? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.timeZone = TimeZone(secondsFromGMT: 0) // normalize to UTC midnight
return formatter.date(from: s)
}
/*
Compare two Date objects.
Returns:
- "earlier"
- "later"
- "equal"
*/
func compareDates(_ a: Date, _ b: Date) -> String {
if a < b { return "earlier" }
if a > b { return "later" }
return "equal"
}
/*
Run a single test case:
- Parse both dates
- Handle invalid input
- Compare if valid
*/
func runTestCase(_ d1: String, _ d2: String) {
guard let a = parseDate(d1), let b = parseDate(d2) else {
print("Compare '\(d1)' vs '\(d2)' → invalid date format")
return
}
print("Compare '\(d1)' vs '\(d2)' → \(compareDates(a, b))")
}
/*
Main test suite:
- Multiple test cases
- Includes edge cases
- Prints results cleanly
*/
func main() {
print("Date comparison tests:\n")
let tests: [[String]] = [
["2024-01-01", "2024-01-02"], // earlier
["2024-01-02", "2024-01-01"], // later
["2024-01-01", "2024-01-01"], // equal
["1999-12-31", "2000-01-01"], // millennium boundary
["2024-02-29", "2024-03-01"], // leap year
["2024-02-29", "2023-02-28"], // leap vs non-leap
["2024-13-01", "2024-01-01"], // invalid month
["2024-00-10", "2024-01-01"], // invalid month
["2024-01-32", "2024-01-01"], // invalid day
["abcd-ef-gh", "2024-01-01"], // invalid format
["2024-01-01", "abcd-ef-gh"] // invalid format
]
for pair in tests {
runTestCase(pair[0], pair[1])
}
}
main()
/*
run:
Date comparison tests:
Compare '2024-01-01' vs '2024-01-02' → earlier
Compare '2024-01-02' vs '2024-01-01' → later
Compare '2024-01-01' vs '2024-01-01' → equal
Compare '1999-12-31' vs '2000-01-01' → earlier
Compare '2024-02-29' vs '2024-03-01' → earlier
Compare '2024-02-29' vs '2023-02-28' → later
Compare '2024-13-01' vs '2024-01-01' → invalid date format
Compare '2024-00-10' vs '2024-01-01' → invalid date format
Compare '2024-01-32' vs '2024-01-01' → invalid date format
Compare 'abcd-ef-gh' vs '2024-01-01' → invalid date format
Compare '2024-01-01' vs 'abcd-ef-gh' → invalid date format
*/