/** * Shared, framework-free time-of-day primitives. * * Every date/time component in the library (DateRangePicker's TimeSelector, * TimePicker, SingleDatePicker's optional time section) builds on these so the * parsing, clamping and formatting rules stay identical across all of them. * * Canonical representation is `TimeValue` — 24-hour `hours` (0-23), `minutes` * (0-59), `seconds` (0-59). The `'12h' | '24h'` format only ever affects * *display*; it never changes the stored value. */ export type TimeValue = { hours: number; minutes: number; seconds: number; }; export type TimeFormat = '12h' | '24h'; export declare const SECONDS_PER_DAY: number; /** Legacy `"HH:mm"` string used by DateRangePicker's internal time state. */ export type TimeString = string; /** * Caller-supplied step values reach these generators straight from props. * `Math.trunc(Infinity) || 1` is still Infinity, so a finite check has to come * before the `|| 1` fallback or the arithmetic downstream produces NaN. */ export declare const sanitizeStep: (step: number) => number; export declare const createTimeValue: (hours: number, minutes?: number, seconds?: number) => TimeValue; export declare const timeValueToSeconds: (time: TimeValue) => number; export declare const secondsToTimeValue: (totalSeconds: number) => TimeValue; export type DateTimeParts = { year: number; month: number; day: number; hours: number; minutes: number; seconds: number; }; export declare const getDateTimeParts: (date: Date, timezone?: string) => DateTimeParts; /** * Builds the instant at which the given wall-clock reading occurs in * `timezone` (machine-local when omitted). * * DST disambiguation follows the standard "compatible" policy (Temporal's * `disambiguation: 'compatible'`, java.time, Luxon): * * - **Gap** (spring-forward; the reading never happens) — resolve *forward* by * the size of the gap. New York 02:30 on 2025-03-09 becomes 03:30, and * midnight in a zone that transitions at midnight (Santiago, Havana) becomes * 01:00 **on the same calendar day**. Resolving backwards instead — which the * old correction loop did in those zones — silently moved the calendar day, * breaking `applyTimeValueToDate`'s contract. * - **Fold** (fall-back; the reading happens twice) — pick the *first*, i.e. * earlier, occurrence. * * Both are resolved explicitly from the zone's offsets rather than left to a * fixed-point iteration, which cannot converge on a gap at all. */ export declare const createDateFromParts: (parts: DateTimeParts, timezone?: string) => Date; /** * Reads the time-of-day off an instant. * * Pass `timezone` whenever the surrounding component is timezone-aware — * omitting it silently mixes a zone-local date with a machine-local time, * which is how a picker ends up displaying one zone's date beside another * zone's clock. */ export declare const timeValueFromDate: (date: Date, timezone?: string) => TimeValue; /** * Replaces the time-of-day of `date`, keeping its calendar day *in `timezone`* * and returning the corresponding instant. * * The calendar day is the hard guarantee — `SingleDatePicker` commits whatever * day comes back out of here, so a shifted day is a wrong selection. DST gaps * are resolved forward by `createDateFromParts`, which normally stays inside * the day (Santiago midnight becomes 01:00 on the same date). A handful of * zones move their clocks at 23:00 instead, so the gap swallows the end of the * day and forward resolution would land on the next one — America/Nuuk on * 2025-03-29 jumps 22:59:59 straight to 00:00. There the day wins and the * result is clamped to the last instant that day actually has. */ export declare const applyTimeValueToDate: (date: Date, time: TimeValue, timezone?: string) => Date; /** Same calendar day as seen from `timezone` (machine-local when omitted). */ export declare const isSameCalendarDayInTimezone: (a: Date, b: Date, timezone?: string) => boolean; /** Canonical machine string: `"HH:mm"`, or `"HH:mm:ss"` when `showSeconds`. */ export declare const timeValueToString: (time: TimeValue, showSeconds?: boolean) => TimeString; /** Parses a canonical `"HH:mm"` / `"HH:mm:ss"` string. Returns null if invalid. */ export declare const timeValueFromString: (value: string) => TimeValue | null; export declare const to12Hour: (hours: number) => { hour: number; period: "AM" | "PM"; }; export declare const from12Hour: (hour: number, period: "AM" | "PM") => number; export type FormatTimeOptions = { format?: TimeFormat; showSeconds?: boolean; }; /** * Human-readable time. `'12h'` produces `"2:30 PM"` / `"2:30:15 PM"`, * `'24h'` produces `"14:30"` / `"14:30:15"`. */ export declare const formatTimeValue: (time: TimeValue, { format, showSeconds }?: FormatTimeOptions) => string; /** Placeholder matching what `formatTimeValue` would produce. */ export declare const getTimePlaceholder: ({ format, showSeconds, }?: FormatTimeOptions) => string; export declare const MIN_TIME: TimeValue; export declare const MAX_TIME: TimeValue; export declare const isTimeWithinBounds: (time: TimeValue, minTime?: TimeValue, maxTime?: TimeValue) => boolean; /** * Clamps into `[minTime, maxTime]`. If the bounds are inverted the min wins, * which keeps the result deterministic rather than throwing at render time. */ export declare const clampTimeValue: (time: TimeValue, minTime?: TimeValue, maxTime?: TimeValue) => TimeValue; export type TimeSlotOptions = { /** Minute granularity. Values < 1 are treated as 1. */ stepMinutes?: number; minTime?: TimeValue; maxTime?: TimeValue; }; /** * Generates the selectable minute-granularity slots for a dropdown-style time * field, inclusive of both bounds. * * Stepping restarts at :00 on every new hour, so the list stays aligned to the * step grid (00/15/30/45 for the default step) even when `minTime` is off-grid * — only the first hour begins at `minTime`'s minute. This mirrors the * long-standing DateRangePicker generator exactly. `TimeSelector`, the mobile * wheel picker (`generatePickerData`) and `createSelectionHandler` all route * through here, so the step can only change in one place. */ export declare const generateTimeSlots: ({ stepMinutes, minTime, maxTime, }?: TimeSlotOptions) => TimeValue[]; /** The discrete values for a single column of a segmented time picker. */ export declare const generateHourOptions: (format?: TimeFormat) => number[]; export declare const generateMinuteOptions: (stepMinutes?: number) => number[]; export declare const generateSecondOptions: (stepSeconds?: number) => number[]; /** Rounds a value to the nearest representable slot on the minute grid. */ export declare const snapToMinuteStep: (time: TimeValue, stepMinutes: number) => TimeValue; export type ParseTimeInputOptions = { minTime?: TimeValue; maxTime?: TimeValue; /** * When no AM/PM is typed and the hour is 1-12, guess the period from the * current wall-clock hour. This is the long-standing DateRangePicker * behaviour; 24-hour pickers should pass `false` so "3" means 03:00. */ ambiguousHourHeuristic?: boolean; /** Injectable clock, for the heuristic above. Tests pass a fixed date. */ now?: Date; /** Reject `"12:30:45"` style input. Minute-only fields pass `false`. */ allowSeconds?: boolean; }; /** * Forgiving parser for free-typed time input. Accepts `"2:30 PM"`, `"14:30"`, * `"1430"`, `"230"`, `"2:30:15 PM"`. Returns null when the input is * unparseable *or* falls outside `[minTime, maxTime]`. */ export declare const parseTimeInput: (input: string, { minTime, maxTime, ambiguousHourHeuristic, now, allowSeconds, }?: ParseTimeInputOptions) => TimeValue | null;