minted_chronology 1.0.2
minted_chronology: ^1.0.2 copied to clipboard
Well-modelled Dart value types for calendar dates and durations: Date, Month, Weekday and Iso8601Duration. Parse, don't validate. Part of the minted family.
minted_chronology #
Calendar dates and durations as well-modelled value types.
Part of the minted family: pure-Dart value types built on
parse, don't validate, so the parser is the only door in and anything that came through it is
well-formed by construction. Once you hold a Date, it is a real calendar date.
Install #
dart pub add minted_chronology
minted comes with it, holding the vocabulary a parse hands back
(ParseOutcome, MintedFailure). Nothing here drags in
another domain's engine.
What's in the box #
| Type | What it guarantees | Standard |
|---|---|---|
Date |
a real calendar date: no time, no zone; impossible dates rejected | ISO 8601 |
Month |
a real month 1-12 that knows its own length (leap-aware) |
building block |
Weekday |
one of seven named days, ISO-numbered 1 (Monday) to 7 (Sunday) |
ISO 8601 |
Iso8601Duration |
a duration with months and years, which dart:core Duration cannot hold |
ISO 8601 |
Date is the type DateTime isn't: no clock, no zone, and an impossible date is refused rather
than rolled over. Weekday is an enum a Date hands back, so a switch over one needs no default
arm.
A quick taste #
final date = Date.tryParse('2026-07-07')!; // strict ISO 8601 YYYY-MM-DD
date.iso8601; // '2026-07-07' (canonical form)
date.weekday; // Weekday.tuesday (.value is 2, matching DateTime.weekday)
date.month.daysIn(2026); // 31 (the month is a Month, and knows its length)
date.tryAddDays(30); // Date(2026-08-06)
date.tryAddDays(3000000); // null (the walk left the 0000-9999 bound)
Date.now(); // today in the local zone, the date-only DateTime.now()
// impossible dates are rejected, not rolled over the way DateTime does:
Date.tryParse('2026-13-01'); // null (no 13th month; DateTime would give 2027-01-01)
// Weekday arithmetic wraps round the week, and bridges back from dart:core:
date.weekday.next; // Weekday.wednesday
Weekday.friday.daysUntil(Weekday.monday); // 3
Weekday.tryFrom(DateTime.now().weekday); // a Weekday, or null
// Iso8601Duration holds components, because a month has no length until anchored to a date:
final span = Iso8601Duration.tryParse('P1Y2M3DT4H')!;
span.months; // 2
span.toDuration(from: Date.of(2026, 1, 31).getOrThrow()); // 427 days and 4 hours
Iso8601Duration.tryParse('PT1M')!.iso8601; // 'PT1M' (a minute; P1M is a month)
Iso8601Duration.tryParse('P1Y2W'); // null: the week form never mixes
The runnable version is the example.
One shape, every type #
Type.tryParse(input)hands back the value, ornullwhen the input isn't validType.parse(input)hands back aParseOutcome: the value, or a typed failure (DateFailure,MonthFailure,Iso8601DurationFailure) you canswitchon, or read as a form-field message via.reasonOrNull. No door throws- value equality, a canonical
.iso8601, chronological ordering (<,isBefore,compareTo), andDate.of/Date.fromDateTimefor parts you already hold Weekdayis a classification rather than a parsed value, so it takestryFrom(isoDayNumber)instead of a parse door
The minted README is the family guide: the package index,
handling failures, and the one caveat (never cast into a minted type).