Time zones, all-day events and recurrence
Model instants, local dates and recurring events without silent assumptions.
Reviewed · 2026-10-25 / Ridian
An instant needs an offset
Section titled “An instant needs an offset”Use an explicit UTC Z or numeric offset in API timestamps: 2026-10-25T10:00:00+01:00. An IANA zone such as Europe/Berlin describes civil-time rules; it does not replace the timestamp’s offset. Avoid ambiguous names such as “CST”.
All-day is a local date
Section titled “All-day is a local date”An all-day event is not always 24 elapsed hours. In Europe/Berlin, 25 October 2026 spans 25 hours because daylight saving time ends. Preserve the local date and use the intended calendar zone when comparing occupied intervals.
CalDAV live queries accept timeZone in MCP or time_zone in REST. If the calendar does not provide a usable zone, Ridian requires an explicit IANA zone instead of silently assuming UTC. Ask the user when the zone is unknown.
Create an all-day event
Section titled “Create an all-day event”Alvin and the MCP tool create_event create genuine all-day events in Google, Microsoft and CalDAV calendars, including Apple iCloud. Set allDay to true and give dates instead of times:
| Field | Meaning |
|---|---|
startDate |
First day, YYYY-MM-DD |
endDate |
Last day, YYYY-MM-DD, included. Omit it for a one-day event |
timeZone |
Your IANA zone. It never shifts the dates |
Example: a trade fair from 27 to 29 October 2026 is "allDay": true, "startDate": "2026-10-27", "endDate": "2026-10-29". The event appears on exactly these three days in every calendar app. An all-day event spans up to 366 days; for an all-day series, use the calendar app. list_events returns such events with showWithoutTime: true.
Title, description, location and availability of an all-day event can be changed with update_event. To move it to another date, use the calendar app; Ridian keeps an all-day event all-day.
A series is not a pile of independent events
Section titled “A series is not a pile of independent events”A recurring series has rules and may contain moved or cancelled occurrences. Reading a range must account for those exceptions. Creating many separate weekly events does not create a native recurring series.
Recurrence with Alvin and MCP
Section titled “Recurrence with Alvin and MCP”| Action | Google and Microsoft | Apple iCloud / CalDAV |
|---|---|---|
| Read existing series, including exceptions | Supported | Supported |
| Create a bounded weekly series without guests | Supported | Use the calendar app |
| Create daily, monthly, yearly or custom recurrence | Use the calendar app | Use the calendar app |
| Change, move or delete one occurrence of your own series without guests | Supported | Supported |
| Rename an entire series or change its description or location | Supported | Supported |
| Change the schedule of an entire series or delete it | Use the calendar app | Use the calendar app |
| Change this and all following occurrences | Use the calendar app | Use the calendar app |
When creating a weekly series, the start and IANA timezone determine one weekday and local time. Repeat every week or every N weeks. Choose 2–104 occurrences including the first, with the last at most 104 weeks after the first. Specify the total count explicitly. The first event must start and end on the same local day; ambiguous local times and events crossing a clock change are excluded from creation.
Example: “In my Google Work calendar, create a series of eight focus blocks without guests, every other Thursday from 10 to 11 am starting 15 October 2026, timezone Europe/Berlin.” In Alvin’s Ask before changes mode, review and confirm the details before creation; Execute automatically carries out permitted requests directly. In MCP, recurrence.frequency=weekly, interval=2 and count=8 describe this pattern; see create_event for the complete schema.
To change one occurrence, name it precisely, for example: “Move next Tuesday’s team sync to 2 pm, only this occurrence.” The assistant reads the series first and changes only the occurrence it found; MCP clients pass the occurrenceId from list_events to update_event or delete_event. To rename the whole series, editScope: "series" changes the title, description or location of all occurrences; occurrences you changed individually can keep their own values, and the schedule stays the same. If the series was changed in the meantime, the change is not applied; read the series again and repeat the request.
Use the calendar app for multiple weekdays such as Monday to Friday, an end date instead of a count, unbounded repetition and custom recurrence rules. Calendar sync has a separate scope.
Series in calendar sync
Section titled “Series in calendar sync”Between Google and Microsoft, Ridian propagates changes and cancellations of individual occurrences in a native series. Times follow the series time zone across daylight saving changes; all-day events retain their date. The content policy also applies to exceptions: busy-only does not copy descriptions or locations.
A series can have at most 1,000 exceptions. Microsoft may reject moving an occurrence past its neighbors. These limits cause a sync error; an incomplete series is not confirmed as successfully synchronized. If calendars disagree, check the connection status and follow sync troubleshooting.
Use bounded windows
Section titled “Use bounded windows”Event and availability queries are limited to 20 calendars and 744 elapsed hours (31 × 24 hours). When daylight saving time ends, 31 local calendar days can span 745 hours. Split longer periods into consecutive windows; each window’s end is exclusive. Ask for the hours you need; a whole-week query includes nights unless you constrain it. For a dense calendar, use smaller windows rather than assuming a partial result is complete. Events that overlap the window are returned with their real start and duration, even if they began earlier. If a calendar or part of the window cannot be read, list_events and search_events still return the other events, and warnings names each affected calendar with the missing UTC ranges or the number of skipped events; the result does not cover those.