How to compare two dates in Swift

1 Answer

0 votes
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

*/

 



answered Sep 20 by avibootz
...