"""
Date comparison in Python
-------------------------
This program demonstrates how to compare two dates using Python's
built‑in datetime module. It uses a modular design, clear comments,
and a full test suite.
Concepts:
- Parsing dates safely
- Comparing datetime.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:
- datetime operations are O(1).
- Parsing is fast and predictable.
- Memory usage is minimal.
Pitfalls:
- Incorrect date formats must be handled.
- Comparing strings directly is unsafe; always convert to date objects.
- Timezones are not used here; for timezone-aware comparisons,
use datetime.datetime with tzinfo.
"""
from datetime import datetime, date
from typing import Optional, Tuple
def parse_date(date_str: str) -> Optional[date]:
"""
Safely parse a date string into a datetime.date object.
Supported format: YYYY-MM-DD
Error handling:
- Returns None if the format is invalid or the date is impossible.
- Avoids raising exceptions in the main test loop.
Complexity:
- O(1) for parsing.
"""
try:
return datetime.strptime(date_str, "%Y-%m-%d").date()
except ValueError:
return None
def compare_dates(d1: date, d2: date) -> str:
"""
Compare two date objects and return a human-readable result.
Returns:
- "earlier"
- "later"
- "equal"
Complexity:
- O(1) comparisons.
"""
if d1 < d2:
return "earlier"
elif d1 > d2:
return "later"
else:
return "equal"
def run_test_case(date1: str, date2: str) -> Tuple[str, str, str]:
"""
Run a single test case:
- Parse both dates
- Handle invalid input
- Compare if valid
Returns a tuple:
(date1, date2, result)
"""
d1 = parse_date(date1)
d2 = parse_date(date2)
if d1 is None or d2 is None:
return (date1, date2, "invalid date format")
result = compare_dates(d1, d2)
return (date1, date2, result)
def main():
"""
Main test suite:
- Multiple test cases
- Includes edge cases
- Prints results cleanly
"""
tests = [
("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
]
print("Date comparison tests:\n")
for d1, d2 in tests:
date1, date2, result = run_test_case(d1, d2)
print(f"Compare '{date1}' vs '{date2}' → {result}")
if __name__ == "__main__":
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
"""