import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException
/*
Compare two dates in Kotlin
---------------------------
This program demonstrates how to compare two dates using Kotlin and the
built‑in java.time API. It uses a modular design, clear comments, and a full
test suite.
Concepts:
- Parsing dates safely (YYYY‑MM‑DD)
- Comparing LocalDate 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:
- LocalDate 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 LocalDate.
- LocalDate is date‑only; no timezone concerns here.
*/
/**
* Safely parse a date string in the format YYYY-MM-DD.
* Returns null if the date is invalid.
*/
fun parseDate(s: String): LocalDate? {
return try {
LocalDate.parse(s, DateTimeFormatter.ISO_LOCAL_DATE)
} catch (_: DateTimeParseException) {
null
}
}
/**
* Compare two LocalDate objects.
* Returns: "earlier", "later", or "equal".
*/
fun compareDates(a: LocalDate, b: LocalDate): String {
return when {
a < b -> "earlier"
a > b -> "later"
else -> "equal"
}
}
/**
* Run a single test case:
* - Parse both dates
* - Handle invalid input
* - Compare if valid
*/
fun runTestCase(d1: String, d2: String) {
val a = parseDate(d1)
val b = parseDate(d2)
if (a == null || b == null) {
println("Compare '$d1' vs '$d2' -> invalid date format")
return
}
println("Compare '$d1' vs '$d2' -> ${compareDates(a, b)}")
}
/**
* Main test suite:
* - Multiple test cases
* - Includes edge cases
* - Prints results cleanly
*/
fun main() {
println("Date comparison tests:\n")
val tests = listOf(
listOf("2024-01-01", "2024-01-02"), // earlier
listOf("2024-01-02", "2024-01-01"), // later
listOf("2024-01-01", "2024-01-01"), // equal
listOf("1999-12-31", "2000-01-01"), // millennium boundary
listOf("2024-02-29", "2024-03-01"), // leap year
listOf("2024-02-29", "2023-02-28"), // leap vs non-leap
listOf("2024-13-01", "2024-01-01"), // invalid month
listOf("2024-00-10", "2024-01-01"), // invalid month
listOf("2024-01-32", "2024-01-01"), // invalid day
listOf("abcd-ef-gh", "2024-01-01"), // invalid format
listOf("2024-01-01", "abcd-ef-gh") // invalid format
)
for ((d1, d2) in tests) {
runTestCase(d1, d2)
}
}
/*
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
*/