package main
import (
"fmt"
"time"
)
/*
Compare two dates in Go
-----------------------
This program demonstrates how to compare two dates using Go's built‑in
time.Time type. It uses a modular design, clear comments, and a full test suite.
Concepts:
- Parsing dates safely (YYYY‑MM‑DD)
- Comparing time.Time 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:
- time.Time 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 time.Time.
- time.Time includes time and timezone; here we normalize to midnight UTC.
*/
/*
Safely parse a date string in the format YYYY-MM-DD.
Error handling:
- Returns an error if the date is invalid.
*/
func parseDate(s string) (time.Time, error) {
layout := "2006-01-02" // Go's reference date format
return time.Parse(layout, s)
}
/*
Compare two time.Time objects.
Returns:
- "earlier"
- "later"
- "equal"
*/
func compareDates(a, b time.Time) string {
if a.Before(b) {
return "earlier"
}
if a.After(b) {
return "later"
}
return "equal"
}
/*
Run a single test case:
- Parse both dates
- Handle invalid input
- Compare if valid
*/
func runTestCase(d1, d2 string) {
a, err1 := parseDate(d1)
b, err2 := parseDate(d2)
if err1 != nil || err2 != nil {
fmt.Printf("Compare '%s' vs '%s' → invalid date format\n", d1, d2)
return
}
fmt.Printf("Compare '%s' vs '%s' → %s\n", d1, d2, compareDates(a, b))
}
/*
Main test suite:
- Multiple test cases
- Includes edge cases
- Prints results cleanly
*/
func main() {
fmt.Println("Date comparison tests:\n")
tests := [][2]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 _, t := range tests {
runTestCase(t[0], t[1])
}
}
/*
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
*/