Skip to content

ADR 0003 own date type

Karthik P edited this page Oct 31, 2026 · 1 revision

ADR-0003: Own date type, no date-crate dependency in the core

The core uses its own compact civil Date type and does not depend on chrono, jiff or time, which may later be supported only as optional conversions.

Last reviewed: 31 Oct 2026

Status

Accepted on 31 Oct 2026. Decided by the research documents: the research proposal ("Ecosystem bindings") and the gap analysis, which says to keep the plan of an own Date type with chrono, jiff and time behind feature flags. The own type is built in 0.1.0; the optional conversions are planned for 0.2 (Roadmap).

Context

The core needs dates for every operation: day arithmetic, weekday, month lengths and ISO formatting, all in the proleptic Gregorian calendar with no time or zone (ADR-0006). Rust has several date crates. The proposal worries about churn in them and cites Jiff, whose README says, as of 31 Oct 2026, "I don't currently have a timeline for a Jiff 1.0 release." (Jiff README). The research documents wrote this as "no timeline", which is a paraphrase, not the README's wording (Evidence).

The core is #![no_std] with alloc so that it builds for WebAssembly and embedded targets, and its dependencies are limited to serde, serde_json and sha2 (crate README, AGENTS.md). Adding any core dependency needs the maintainer's agreement.

Decision drivers

  • No exposure to another crate's breaking releases in the public API.
  • no_std and WebAssembly builds.
  • Cheap comparison and difference, because the differential test walks every day from 1900 to 2200.
  • Rust users who already hold chrono, jiff or time values should be able to pass them in.

Considered options

Option 1: Depend on chrono

Pros:

  • Widely used; users can pass their existing values directly.

Cons:

  • Its date type would appear in fiscalclock's public API, so a chrono major release would force a fiscalclock major release.
  • More code than the core needs: it carries times and zones the core never uses.

Option 2: Depend on jiff

Pros:

  • Modern API with civil date types.

Cons:

  • Pre-1.0 with no 1.0 timeline as of 31 Oct 2026 (Jiff README), so the same public-API coupling as Option 1, with less stability.

Option 3: Depend on time

Pros:

  • Small and has a civil Date.

Cons:

  • The same coupling problem as Options 1 and 2.

Option 4: Own Date type, conversions behind optional features (chosen)

Pros:

  • The core controls the representation: Date wraps an i32 day number (date.rs), so comparison and difference are integer operations.
  • No date crate in the dependency tree of the core.

Cons:

  • The core must implement and test Gregorian arithmetic itself. The conformance vectors and the ISO 8601 oracle (check C15 in research/verification/) are what make that safe.
  • Until the optional features ship, Rust users convert by hand, for example through ISO strings.

Decision

Option 4. fiscalclock::Date is a proleptic Gregorian civil date in the years 0001 to 9999, stored as an i32 day number, with from_ymd and strict YYYY-MM-DD parsing. Conversions from chrono, jiff and time dates are planned behind cargo features in 0.2; they are not in 0.1.0.

Consequences

Good:

  • The core's public API has no third-party date types, so their releases cannot break it.
  • The same i32 day numbers are the planned bulk representation for JavaScript (Int32Array) and Arrow.

Bad:

  • Date arithmetic is project code and needs its own tests; a bug there affects every result. The differential test against a slow day-by-day reference implementation covers every date from 1900 to 2200 (Testing-Strategy).
  • Adding the optional conversions later means adding optional dependencies to the core, which needs the maintainer's agreement under AGENTS.md.

Links

Clone this wiki locally