Actual starts and timezone evidence, locally

iCalendar Recurrence, DST & Time-Zone Expansion Auditor

Paste a calendar or recurrence rule and see the starts it produces. Compare nominal clocks, UTC instants, and a display timezone; inspect skipped dates, repeated times, exclusions, and duplicate contributions before relying on the schedule.

Bounded RFC 5545 model

Calendar and expansion window

Up to 1 MiB and 32 events. UTF-8 text, line folding, repeated RDATE/EXDATE properties, DATE and DATE-TIME values are supported. Unsupported recurrence features remain unresolved.

No local file selected.

Use an IANA name or a supported embedded TZID. DATE values have no timezone and are filtered by their calendar date. Timed starts are filtered by UTC instant. Maximum window: 3,660 days.

The teaching calendar is ready.

Calendar text, event names, identifiers, timezone definitions, and reports stay in this browser tab. ToolQuill does not upload the calendar, subscribe to URLs, connect to accounts, send invitations, or execute alarms.

How the recurrence set is formed

The start set combines DTSTART, RRULE, and RDATE. Duplicate identities are merged. EXDATE then removes matching starts, including DTSTART if listed; an exclusion does not replenish COUNT. Timed identities compare resolved UTC instants, while all-day identities compare dates. Separate series that coincide in time remain separate events.

COUNT includes DTSTART and is evaluated from the series origin before filtering to your requested window. UNTIL is inclusive and must use the appropriate value form: DATE for all-day events, a floating date-time for floating events, and UTC for UTC or TZID starts. A DTSTART that does not match its RRULE leaves the set undefined under RFC 5545, so this tool marks the series unresolved.

Gaps and repeated clock times are different cases

A generated RRULE instance at a nonexistent clock time is skipped without consuming COUNT. Invalid calendar dates, such as February 31, are also skipped rather than normalized into another month. This can move the last counted occurrence later than a simple interval calculation suggests.

An explicit DTSTART or RDATE in a forward clock gap is interpreted using the offset before the gap; the table shows both the nominal value and the effective local clock. A backward transition can give one clock value two UTC instants. RFC 5545 chooses the first occurrence; the alternative UTC instant is shown as diagnostic evidence, without inventing a second included event.

Source offset changes and elapsed UTC hours help explain why a weekly local event can be 167 or 169 hours from its previous start. These comparisons use adjacent included rows for that series inside the window; exclusions and added RDATEs can also change the elapsed interval.

Supported rule and timezone model

The model supports DAILY, WEEKLY, MONTHLY, and YEARLY with INTERVAL, COUNT or UNTIL, WKST, BYMONTH, BYMONTHDAY (including negative positions), BYDAY (including supported monthly/yearly ordinals), BYHOUR, BYMINUTE, BYSECOND from 0–59, and BYSETPOS. Constraints and intersections follow this bounded model; unsupported or invalid combinations stop expansion of that series.

UTC, floating DATE-TIME, all-day DATE, and browser-recognized IANA TZIDs are supported. Supported embedded VTIMEZONE definitions take precedence over the browser database: STANDARD/DAYLIGHT DTSTART, offsets, explicit RDATE transitions, and bounded YEARLY rules must produce a continuous, unambiguous offset history. Before the first supplied transition, the earliest TZOFFSETFROM is used. Embedded definitions are not checked against IANA or a server.

The source of each series’ offsets is visible. Browser IANA data can differ between devices or become outdated. Floating times have no timezone in the original calendar: the selected interpretation is an explicit audit assumption. All-day DATE values remain dates.

Expansion boundaries

This is a start-time audit, not a complete calendar client or conformance validator. It excludes subdaily FREQ values, BYWEEKNO, BYYEARDAY, RSCALE/SKIP, leap seconds, EXRULE, RDATE periods, multiple RRULEs, detached RECURRENCE-ID overrides, RANGE=THISANDFUTURE, cancellation/version reconciliation, VTODO/VJOURNAL expansion, event duration/end calculation, alarm execution, and invitation semantics. BYSETPOS over a period containing nonexistent local times leaves the series unresolved. Every component sharing an overridden or duplicated UID is marked unresolved.

Input dates are bounded to 1900–2100, the window to 3,660 days, output to 10,000 distinct candidates/occurrences and diagnostic rows, each recurrence period to 20,000 candidates, and total work to 300,000 steps. A resource limit aborts the audit instead of presenting a truncated schedule. Supported series can still be inspected when another series is unresolved; the summary and exports clearly mark that audit incomplete. Confirm critical schedules in the receiving calendar client with its timezone data and exception model.

Primary specification

RFC 5545 defines iCalendar content lines, DATE/DATE-TIME values, recurrence rules, VTIMEZONE, RDATE, and EXDATE. The relevant behavior is in sections 3.3.5, 3.3.10, 3.6.5, 3.8.5.1, 3.8.5.2, and 3.8.5.3. Parameter caret escapes follow RFC 6868. This tool’s supported subset and limits are listed above.

Frequently asked questions

Why does COUNT=4 show only three starts?

COUNT limits the underlying recurrence, including DTSTART. EXDATE can remove a counted start, and the window can hide starts before or after your selected dates. RDATE adds starts independently. Gap and invalid-date skips do not consume COUNT.

Why do I see a floating-time warning?

A DATE-TIME without Z or TZID is a floating clock value. Its instant depends on where it is interpreted. The audit uses your explicit floating-time zone and records that assumption in the report.

Will an imported calendar always behave the same way?

No. Clients can use different timezone databases, embedded definitions, exception models, or unsupported extensions. This audit makes its model and unresolved features visible so you can compare the result with the target client.

Can I paste just an RRULE?

Choose RRULE input, supply the compact DTSTART and optional TZID, and add optional RDATE/EXDATE property lines. The tool creates a local property block for expansion; source-line evidence refers to that block.

Browse calendaring tools · Inspect systemd calendar timers