import type { JsonValue } from '../../types.ts';
export declare const WINDOW_AHEAD_DAYS = 90;
export declare const SPAN_SEP = "--";
/**
 * Resolve an IANA zone name, falling back to UTC when unknown.
 *
 * A calendar can name a zone this platform's ICU data does not carry.
 * Failing the whole listing over it would let one bad calendar hide every
 * other one, so fall back and keep going.
 */
export declare function zone(tz: string): Intl.DateTimeFormat;
/** The wall-clock reading an instant has in a zone. */
export declare function wallParts(instant: number, tz: string): {
    year: number;
    month: number;
    day: number;
    hour: number;
    minute: number;
    second: number;
};
/** The instant at which a local calendar day begins. */
export declare function localMidnight(day: string, tz: string): number;
/** The `YYYY-MM-DD` a day-count offset lands on, in floating date space. */
export declare function shiftDay(day: string, days: number): string;
/** The local date an instant falls on, `YYYY-MM-DD`. */
export declare function localDate(instant: number, tz: string): string;
/**
 * The RFC3339 timeMin/timeMax pair covering local days from one day.
 *
 * Computed as local midnights rather than start + 24h: a local day is 23 or
 * 25 hours on the two DST transitions each year, and adding a fixed day
 * would drop or double an hour of events.
 */
export declare function dayBounds(day: string, tz: string, days?: number): [string, string];
/**
 * The first day of the bucket that holds a day.
 *
 * Buckets tile a fixed grid from `BUCKET_EPOCH` rather than one centred on
 * today, so a directory name means the same days whenever it is listed. The
 * first bucket of the calendar era is cut short at `0001-01-01` instead of
 * starting before it.
 */
export declare function bucketStart(day: string, size: number): string;
/**
 * The directory name of the bucket opening on a day.
 *
 * A one-day bucket is spelled as the day, which keeps the default tree as it
 * was; a longer one names its first and last day, so the name says which
 * days it holds without the reader knowing the mount's size.
 */
export declare function bucketName(start: string, size: number): string;
/**
 * Whether a name is shaped like a bucket: a real day or a span of two.
 *
 * Shape only: whether the bucket lies on a mount's grid depends on that
 * mount's size, which `parseBucket` checks.
 */
export declare function validBucket(name: string): boolean;
/**
 * The first day of the bucket a name spells on a mount's grid, or null.
 *
 * Each bucket has exactly one spelling per mount: a span off the grid, of
 * the wrong length, or a bare day on a multi-day mount spells none.
 */
export declare function parseBucket(name: string, size: number): string | null;
/**
 * Default listing: all past events, with a finite future horizon.
 *
 * The horizon, the end of the bucket holding the day `WINDOW_AHEAD_DAYS`
 * past today, is what keeps a recurring event without an end from expanding
 * forever; ending on a bucket edge decides the last bucket on all of its
 * days.
 */
export declare function windowBounds(today: string, tz: string, size?: number): [null, string];
/**
 * Whether a string is a real calendar date, not merely date-shaped.
 *
 * `2026-02-30` matches the shape and is not a day; letting it through made
 * stat report a directory that every later call then failed on.
 */
export declare function validDay(day: string): boolean;
/**
 * Resolve one event time slot to an absolute instant.
 *
 * A dateTime with no offset is a zoned event, not an error: Google requires
 * an offset unless the slot names its own zone. Reading it in the host zone
 * would silently move the event.
 */
export declare function slotInstant(slot: Record<string, JsonValue>, tz: string): number | null;
/**
 * The absolute [start, end) span of an event.
 *
 * An all-day event's `end.date` is exclusive, so a one-day event is
 * `start=D, end=D+1` and its span closes at the midnight opening the next
 * day. That is the same convention the instant carries, so no adjustment is
 * applied here.
 */
export declare function eventSpan(event: Record<string, JsonValue>, tz: string): [number, number] | null;
/**
 * Every local day an event's span touches.
 *
 * The end is exclusive, so an event closing exactly at local midnight does
 * not reach into the following day; a zero-length event still occupies the
 * day it starts on.
 */
export declare function daysCovered(span: [number, number], tz: string): string[];
/**
 * The `HHMM-HHMM` label for an event as seen on one local day.
 *
 * Times are clamped to the day, so an event running through it reads
 * `0000-2400` rather than repeating times that belong to another day.
 * `2400` is how an end at the next local midnight is spelled, since `0000`
 * there would sort before the start.
 */
export declare function clampedHhmm(span: [number, number], day: string, tz: string): string;
//# sourceMappingURL=day.d.ts.map