How do I parse a date from a string in EK9?
← Date, Time, and Duration · Ref: Q538
EK9 uses constructor parsing: pass a string to Date(), Time(), or DateTime() and use guard expressions to handle invalid input safely.
CONSTRUCTOR PARSING
Date('2024-01-15') parses ISO 8601 date format.
Time('10:30:00') parses ISO 8601 time format.
DateTime('2024-06-15T10:30:00Z') parses ISO 8601 datetime format.
INVALID INPUT PRODUCES UNSET
If the string is not a valid format, the constructor returns an unset value rather than throwing an exception:
badDate <- Date('not-a-date') badDate? is false
This follows EK9's tri-state design: invalid parsing produces unset, not an error.
GUARD PATTERN FOR SAFE PARSING
Combine constructor parsing with guard expressions for clean error handling:
if parsed <- Date(userInput) stdout.println(`Valid date: ${parsed}`) else stdout.println('Invalid date format')
The guard only enters the if-block when the parsed value is set.
ROUND-TRIPPING
The $ operator produces a string that can be parsed back:
original <- 2024-06-15 asString <- $original restored <- Date(asString) require restored == original
See Q31 for Date and Time basics. See Q552 for Date-to-DateTime promotion. See Q555 for constructing from components.
Example
defines module qa.parse.date.string defines program ParseDateStringDemo() stdout <- Stdout() // Parse valid ISO 8601 strings parsedDate <- Date("2024-01-15") parsedTime <- Time("10:30:00") parsedDT <- DateTime("2024-06-15T10:30:00Z") stdout.println(`Parsed date: ${parsedDate}`) stdout.println(`Parsed time: ${parsedTime}`) stdout.println(`Parsed datetime: ${parsedDT}`) require parsedDate? require parsedTime? require parsedDT? // Invalid strings produce unset values badDate <- Date("not-a-date") badTime <- Time("invalid") badDT <- DateTime("garbage") require ~badDate? require ~badTime? require ~badDT? stdout.println(`Bad date isSet: ${badDate?}`) stdout.println(`Bad time isSet: ${badTime?}`) // Guard pattern for safe parsing userInput <- "2024-03-20" if validDate <- Date(userInput) stdout.println(`Valid: ${validDate}`) invalidInput <- "31/02/2024" if checkedDate <- Date(invalidInput) stdout.println(`This won't print`) else stdout.println("Invalid date format") // Round-tripping: $ produces parseable string original <- 2024-06-15 asString <- $original restored <- Date(asString) require restored == original stdout.println(`Round-trip: ${original} -> ${asString} -> ${restored}`) // Duration parsing also returns unset on invalid validDur <- Duration("P1Y6M") invalidDur <- Duration("not-a-duration") require validDur? require ~invalidDur? stdout.println(`Valid duration: ${validDur}`)
Common mistakes
E50001 — Renaming the variable means later references to 'parsedDate' become unresolved, triggering E50001. See ek9 -h E50001 for details.
Incorrect:
parsedDateXYZ <- Date("2024-01-15")
Correct:
parsedDate <- Date("2024-01-15")
E50001 — Renaming the variable means later references to 'userInput' become unresolved, triggering E50001. See ek9 -h E50001 for details.
Incorrect:
userInputXYZ <- "2024-03-20"
Correct:
userInput <- "2024-03-20"
Other ways to ask this
- How do I convert a string to a date in EK9?
- How do I handle invalid date strings in EK9?
- How does Date construction from strings work?
Coming from another language?
Java: LocalDate.parse() throws DateTimeParseException on invalid input, requires try-catch. Python: datetime.strptime() throws ValueError, requires try-except. JavaScript: new Date('invalid') returns 'Invalid Date' object (truthy!). Go: time.Parse() returns error. Rust: NaiveDate::parse_from_str() returns Result. EK9: constructor returns unset value on invalid input, guard expression handles it cleanly.
Keywords: time, date, safe, unset, round-trip, guard, iso8601, constructor, timezone, isset, invalid, null-safe, duration, convert, parse, string