Guide
Calendar API Time Zone Handling Explained
One meeting, three names for its zone: America/Los_Angeles to Google, Pacific Standard Time to Microsoft Graph, PST to your users. How each calendar API encodes time zones, and where that breaks.
Written by Hazik Director of Product Management
Reviewed by Qasim Muhammad
Command references used in this guide: nylas calendar events create, nylas calendar events update, and nylas calendar events list.
Why do Google and Microsoft Graph use different time zone names?
The Google Calendar API identifies time zones with IANA Time Zone Database IDs such as America/Los_Angeles, while Microsoft Graph natively uses Windows zone names such as Pacific Standard Time. Both describe the same offset-and-DST rules, but the vocabularies differ in size and shape, so code that bridges the two APIs needs a mapping table between them.
Per Google's events reference, an event's timeZone must be an IANA Time Zone Database name — the database maintained at iana.org and updated several times a year as governments change their rules. Graph's dateTimeTimeZone documentation states the property “can be set to any of the time zones currently supported by Windows, as well as the other time zones supported by the calendar API” — so Graph accepts IANA IDs on write. On read, Graph returns start and end in UTC unless you request a zone with the Prefer: outlook.timezone header, and the zone names it returns use the Windows format by default. The granularity gap is real: Windows ships roughly 140 zones, and a single name like Pacific Standard Time covers what IANA splits into America/Los_Angeles and America/Vancouver, while America/Tijuana gets its own Pacific Standard Time (Mexico) zone.
# The same 10:00 Pacific meeting, three encodings
Google Calendar API: "start": { "dateTime": "2026-06-15T10:00:00-07:00",
"timeZone": "America/Los_Angeles" }
Microsoft Graph: "start": { "dateTime": "2026-06-15T10:00:00.0000000",
"timeZone": "Pacific Standard Time" }
iCalendar (RFC 5545): DTSTART;TZID=America/Los_Angeles:20260615T100000How do all-day events handle time zones?
All-day events sidestep time zones entirely: they store a calendar date with no clock time and no zone reference. Google's events resource uses a date field instead of dateTime, with an exclusive end date, and Microsoft Graph sets isAllDay: true with midnight-to-midnight boundaries. A birthday on June 15 is June 15 everywhere on Earth.
The classic bug is parsing that date as midnight UTC. JavaScript's new Date("2026-06-15") does exactly this, so any viewer west of Greenwich sees June 14 — offsets in the IANA database run from UTC-12:00 to UTC+14:00, and every viewer at a negative offset, the entire Americas included, gets the previous day. The second trap is the exclusive end: a 1-day Google all-day event ends on the following date, so a June 15 birthday has end.date of June 16. Treat the pair as a half-open interval, never subtract a day blindly.
The nylas calendar events create command builds all-day events with a single flag, passing a bare date as the start. It writes the provider-correct shape on Google and Microsoft accounts, so the exclusive-end bookkeeping happens once, in the tool, instead of in every script you ship.
# One date, no clock time, no zone
nylas calendar events create \
--title "Company offsite" \
--start "2026-06-15" \
--all-dayWhat happens to recurring events when DST shifts the clock?
A recurring event anchored to a named time zone keeps its local wall time across daylight saving transitions: a weekly 09:00 standup in America/New_York stays 09:00 while its UTC equivalent jumps from 14:00 to 13:00 and back, twice a year. Series expanded against a fixed UTC offset drift by exactly 1 hour after each transition.
The United States has switched on the second Sunday of March and the first Sunday of November since 2007, the European Union on the last Sundays of March and October — about 70 countries observe some form of DST, each on its own schedule. This is why RFC 5545 ties recurrence to zone-aware start times but demands an absolute endpoint: when a series start carries a zone reference, “the UNTIL rule part MUST be specified as a date with UTC time.” Local wall time defines each occurrence; UTC defines where the series stops. For the RRULE grammar itself and how each provider expands a series into instances, see the recurring events guide. A sync bug that only appears in March or November is almost always an expander using the wrong clock.
How do I pin an event to one time zone with the Nylas CLI?
The nylas calendar events create command accepts a --lock-timezone flag that pins the event to the zone it was created in, so it always displays in that zone instead of floating to each viewer's calendar settings. Reverse it later with --unlock-timezone on nylas calendar events update.
Floating display is usually what you want — a call moves with each attendee's clock. Locking is for events tied to a physical place: a 09:00 venue check-in in Lisbon should read 09:00 to a participant in Toronto, not 04:00. A 5-person invite can span 5 zones, and the lock removes the per-viewer conversion for all of them. The create command also runs a DST conflict check on the requested slot and warns before booking; pass --ignore-dst-warning to skip it in scripts. Pair the lock with repeated --participant flags and the invite goes out from your connected account, as covered in the calendar invites guide.
# Pin a venue-bound event to its local zone
nylas calendar events create \
--title "Venue check-in" \
--start "2026-09-10 09:00" \
--end "2026-09-10 09:30" \
--location "Lisbon Congress Centre" \
--participant "ops@example.com" \
--lock-timezone
# Let it float again later
nylas calendar events update <event-id> --unlock-timezoneHow do I read calendar events in a different time zone?
The nylas calendar events list command renders event times in your local zone by default and converts to any IANA zone with --timezone. Add --show-tz to print abbreviations like PST or EST next to each time, which makes a cross-zone agenda readable at a glance.
Conversion at display time is the safe half of time zone work: the stored event never changes, only the rendering. The command shows the next 7 days and 10 events by default, and auto-paginates when you raise --limit past 200. For scripting, --json returns the raw start and end data so jq or your own code can convert with a proper tz library instead of offset arithmetic. To go beyond reading — computing overlap windows across attendees before you book — the cross-timezone scheduling guide covers nylas timezone find-meeting and friends.
# This week's agenda, rendered in Pacific time with abbreviations
nylas calendar events list --timezone America/Los_Angeles --show-tz
# Two weeks of raw event data for scripts
nylas calendar events list --days 14 --jsonNext steps
- Exchange Server Calendar API Options — EWS retires for Exchange Online on October 1, 2026.
- Google Calendar API Quotas and Limits — Google Calendar API quota reference
- Schedule meetings across time zones from the CLI — find overlap windows before you create the event
- Recurring Calendar Events: RRULE Explained — the recurrence grammar behind the DST behavior above
- Create calendar invites from the command line — participants, RSVP tracking, and invite delivery
- Acuity Scheduling API alternatives — building booking flows on a calendar API
- OnSched vs Nylas — scheduling infrastructure compared
- Full command reference — every calendar events flag documented
- RFC 5545 (iCalendar) — the recurrence and TZID rules quoted in this guide
- Microsoft Graph dateTimeTimeZone resource — Windows zone names and accepted formats
- Google Calendar API events reference — IANA timeZone and all-day date fields