Laws for Calendar Intervals

knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
knitr::read_chunk(
  system.file("examples", "calendar-laws.R", package = "s7contract")
)

Whole days from integer offsets

Calendar intervals promise to include both endpoints. Testing that promise needs ordered bounds, queries at those bounds, and ordinary dates between or outside them.

This recipe maps integer offsets onto a fixed Date origin. Size zero draws the origin; size s draws uniformly within origin ± s days, clipped to the bounds. Shrinking moves offsets toward zero. Its Date prototype preserves the class when composed into vectors, including empty and nested vectors.


Bounds and origins must be finite whole dates. This recipe restricts their day counts and the offsets from the origin to R's non-missing integer range. It generates calendar days without a time zone or a dependency on today's date. R's Date documentation warns that fractional day values can be hidden by printing, and that integer and double storage can represent the same date. The law compares dates with ==, <=, and >= rather than requiring identical storage.

An inclusive interval protocol

The class validator requires ordered whole-day bounds. The interface requires a membership operation accepting dates and returning logical values.


Dependent generators rebuild valid intervals as their start or end shrinks. Query generation explicitly includes both endpoints and leap day. Coverage records those cases and intervals crossing New Year.


An end date accidentally excluded

Changing <= to < keeps the required method available but violates the law. The reduced failure is a one-day interval queried on that same day.


Replay the failure with its recorded parameters:




Try the s7contract package in your browser

Any scripts or data that you put into this service are public.

s7contract documentation built on Sept. 10, 2026, 1:09 a.m.