Date reads a date or a time from text: an exact form such as
2026-10-09 09:30, or a relative one such as tomorrow, +2 days or
next monday. It answers a chrono::DateTime, so you compare, format and
store the result with chrono, and the relative forms read the clock the
framework reads, so a test that freezes the clock freezes them too.
use Date;
let due = parse?; // DateTime<Utc>
let expires = parse?;
let launch = parse?;
assert!;
# Ok::
The forms it reads
Date::parse(text) reads these forms, ignoring case and extra spaces,
and answers a time in UTC:
| Form | Example | Answers |
|---|---|---|
| RFC 3339 | 2026-10-09T12:00:00+02:00 |
That moment |
| A date | 2026-10-09 |
That day at midnight |
A date and a time, with a space or T |
2026-10-09 09:30, 2026-10-09T09:30:15.250 |
That time |
| Unix seconds | @1791547200 |
That moment |
| A word | now, today, tomorrow, yesterday, midnight, noon |
See below |
| A count of units from now | +2 days, -30 minutes, 5 hours, 3 weeks ago |
See below |
| A weekday | monday, next friday, last sunday |
That day at midnight |
| The first or last day of a month | first day of next month, last day of this month |
That day, at the current time |
| A word form and a time | tomorrow 09:30, next monday 08:00, last day of this month 23:59 |
That day at that time |
The units are second, minute, hour, day, week, fortnight,
month and year, singular or plural. N <unit> ago counts back.
The time of day follows PHP's relative formats, which Laravel's Date
reads through Carbon:
today,tomorrow,yesterdayandmidnightare at midnight, andnoonat 12:00.- A weekday is at midnight. A weekday alone is today when today is that
day;
nextis strictly after today andlaststrictly before. now, a count of units and the first or last day of a month keep the current time of day.- A time after a word form,
HH:MM, sets the time.
Days, weeks, fortnights, months and years move the calendar date and keep the wall-clock time; seconds, minutes and hours move the moment. A month that has no such day overflows into the next month, as PHP's does: one month after January 31 is March 3 in a common year.
Text it does not read is an error, a DateParseError that names the
text:
use Date;
let error = parse.unwrap_err;
assert_eq!;
DateParseError converts into FrameworkError, so a handler can use ?.
Time zones
Date::parse_in(text, tz) reads the same forms in a time zone and
answers a DateTime<Tz>. A date, a time without an offset and every
relative form are taken in that zone, so tomorrow is the next midnight
in Paris:
use ;
let paris: Tz = "Europe/Paris".parse.expect;
let tomorrow = parse_in?;
let meeting = parse_in?; // 07:30 UTC
# Ok::
A local time that a daylight-saving change skips moves forward by the
length of the skip, as PHP's does: 2026-03-29 02:30 in Paris is 03:30.
A local time that a change repeats is the earlier of the two.
Date::raw_parse(text) is the same as Date::parse. Laravel's rawParse
skips the hook Carbon runs on every parse, and Suprnova has no such hook.
Testing with a frozen clock
Every relative form reads suprnova::clock::now(), so freeze the clock
with TestClock to test code that parses relative dates:
use ;
use Date;
use TestClock;
See Testing for TestClock.
Why Suprnova diverges
- A named set of forms. Carbon reads PHP's whole relative-format
grammar, including forms such as
third friday of next monthor+1 week 2 days.Date::parsereads the forms listed above and refuses the rest, because a form read differently from PHP would be worse than a form refused. Combine forms with chrono's arithmetic instead. - Only English weekday names, spelled in full. PHP also reads
abbreviations such as
mon. - A time follows a word form only. PHP reads
+2 days 09:30; here a count of units takes no time after it. - It answers chrono types. Laravel answers a mutable Carbon instance;
here you get a
DateTime<Utc>orDateTime<Tz>value.
Next
- Strings - the other text helpers
- Localization - formatting a date for a reader's locale
- Testing -
TestClockand the other test helpers
