ICS Time Zone Errors Explained (TZID, VTIMEZONE, Z vs Local)
Why ICS files break across Google Calendar, Outlook, Apple Calendar — and how to fix them
ICS time zone errors are one of the top reasons calendar imports fail or show the wrong time.
Whether you’re generating ICS files in your app, exporting them from a legacy system, or ingesting files from customers, you’ll run into issues like:
-
Invalid TZID (“EST”, “CST”, “GMT-5”)
-
Missing or incorrect VTIMEZONE blocks
-
Events showing the wrong time in Google Calendar / Outlook / Apple Calendar
-
Recurring events shifting an hour during Daylight Savings
-
UTC vs floating times confusion
This guide explains, clearly and practically:
-
what
TZIDactually means, -
how VTIMEZONE blocks work (and why they’re awful),
-
when to use
Z(UTC) vs local time, -
why calendar clients disagree about time zone rules, and
-
how to fix these errors automatically.
1. What TZID Really Means (and Why “EST” Is Invalid)
In ICS files, a timestamp looks like:
DTSTART;TZID=America/New_York:20250310T090000
The TZID must be:
-
a valid IANA time zone name, like
America/New_York -
not Windows zones (
Eastern Standard Time) -
not abbreviations (
EST,CST,PST) -
not offset-style strings (
GMT-5)
❌ Invalid TZIDs (common real-world examples)
TZID=EST
TZID=CST
TZID=GMT-5
TZID=EDT
TZID=PST
These look reasonable to humans, but ICS considers them invalid.
Google Calendar and Apple Calendar will silently reject or misinterpret them.
✔️ Valid TZIDs
TZID=America/New_York
TZID=Europe/Berlin
TZID=Asia/Tokyo
TZID=Australia/Sydney
2. Why Calendar Clients Interpret Time Zones Differently
ICS time zone behavior varies by platform:
Platform
Accepts invalid TZIDs?
Requires VTIMEZONE?
Notes
Google Calendar
❌ No
❌ No
Accepts IANA only; very strict
Apple Calendar (macOS/iOS)
⚠️ Sometimes
✔️ Usually
Tolerates some invalid TZIDs
Outlook Desktop
⚠️ Sometimes
✔️ Yes
Older Outlook needs VTIMEZONE
Outlook Web / Office 365
❌ No
❌ No
Behaves more like Google
Exchange
❌ No
✔️ Yes
Prefers explicit VTIMEZONE blocks
This inconsistency is why an ICS that works in Apple Calendar may fail in Google or Outlook Web.
3. What a VTIMEZONE Block Is (and Why It’s a Mess)
A VTIMEZONE block describes daylight savings rules for a specific geographic region.
Typical Example
ics
Copy code
BEGIN:VTIMEZONE TZID:America/New_York BEGIN:STANDARD DTSTART:20241103T020000 TZOFFSETFROM:-0400 TZOFFSETTO:-0500 RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU END:STANDARD BEGIN:DAYLIGHT DTSTART:20240310T020000 TZOFFSETFROM:-0500 TZOFFSETTO:-0400 RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU END:DAYLIGHT END:VTIMEZONE
Why this causes pain
-
It’s huge and verbose.
-
Rules change historically (DST laws, politics, etc.).
-
Many exporters generate incomplete or wrong blocks.
-
Some clients require it; others ignore it.
-
Some ICS libraries generate outdated or invalid rules.
When you MUST include VTIMEZONE
-
Outlook Desktop
-
Exchange
-
Systems using proprietary/legacy ICS parsers
-
If you use local times without Z suffix
4. Z vs Local Time — What’s the Difference?
ICS time values can be:
1. UTC (“Zulu time”)
makefile
Copy code
DTSTART:20250310T140000Z
-
Ends with
Z -
No TZID
-
Universally supported
-
No VTIMEZONE needed
-
Safe for most use cases
2. Local time with TZID
makefile
Copy code
DTSTART;TZID=America/New_York:20250310T090000
-
Needs a valid TZID
-
Sometimes needs VTIMEZONE
-
May shift differently across clients
-
Required for certain use cases (recurring events at local noon)
3. Floating time (no TZID, no Z)
makefile
Copy code
DTSTART:20250310T090000
-
Means: “Occurs at 9AM in whatever the user’s local time zone currently is”
-
Rarely what developers intend
-
Very likely to cause support tickets
5. Common Time Zone Errors (With Real Examples)
Error 1 — “TZID=EST” or “TZID=CST”
Most ICS exporters try this:
ics
Copy code
DTSTART;TZID=EST:20250310T090000
Why it fails
EST is ambiguous:
-
Could mean North America
-
Could mean a random Caribbean zone
-
Could mean “European Summer Time” in some old systems
ICS requires IANA TZIDs only.
Corrected
ics
Copy code
DTSTART;TZID=America/New_York:20250310T090000
Error 2 — Missing or mismatched VTIMEZONE block
Broken
ics
Copy code
DTSTART;TZID=America/Chicago:20250310T090000
…but no VTIMEZONE matching America/Chicago.
Result
-
Outlook Desktop: broken
-
Apple Calendar: maybe works
-
Google Calendar: works (because it ignores VTIMEZONE)
Corrected
Add a proper VTIMEZONE block or switch to UTC.
Error 3 — RRULE shifts an hour during DST
Recurring events often shift by one hour in:
-
Google Calendar
-
Apple Calendar
-
Outlook Web
-
Teams
Broken (creates DST drift)
ics
Copy code
DTSTART;TZID=America/Denver:20250310T090000 RRULE:FREQ=WEEKLY;BYDAY=MO
If VTIMEZONE is incorrect, this event may eventually drift.
Corrected
-
Use proper VTIMEZONE
-
Or convert to UTC for recurrence if allowed
Error 4 — Local time but missing TZID
Broken
ics
Copy code
DTSTART:20250310T090000
User’s calendar app interprets this using their own settings, not yours.
Corrected
ics
Copy code
DTSTART;TZID=America/New_York:20250310T090000
Error 5 — Using Windows Time Zones
ics
Copy code
TZID=Eastern Standard Time
ICS does not support Windows zones (used by Exchange/Outlook internally).
6. Best Practices for ICS Time Zones
✔️ Use IANA TZIDs only
America/New_York, not EST.
✔️ Prefer UTC where possible
Avoid DST strangeness.
✔️ Include VTIMEZONE when using local times
Especially for compatibility with Outlook.
✔️ Validate ICS before sending to customers
Silent failures are painful.
✔️ Normalize time zones at ingestion
A vendor may send you:
ini
Copy code
TZID=GMT TZID=Etc/GMT+5 TZID=US/Eastern TZID=EST5EDT
Normalize to one standard (IANA).
7. How CorrectICS Fixes Time Zone Issues Automatically
CorrectICS automatically:
-
rewrites invalid TZIDs → valid IANA identifiers
-
inserts VTIMEZONE blocks when required
-
removes inconsistent VTIMEZONE blocks
-
converts local times to UTC if configured
-
fixes malformed DTSTART/DTEND
-
resolves ambiguous DST rules
-
applies consistent line folding
-
prevents infinite or malformed RRULE drift
Whether you use the web UI or the API, time zone issues are the most reliably fixed category.
8. Programmatic Time Zone Validation (Node, Python, Bash)
Node.js
js
Copy code
const data = readFileSync("event.ics"); const res = await fetch("https://api.correctics.com/v1/validate", { method: "POST", headers: { "Content-Type": "text/calendar" }, body: data }); console.log(await res.json());
Python
python
Copy code
res = requests.post( "https://api.correctics.com/v1/validate", headers={"Content-Type": "text/calendar"}, data=open("event.ics","rb") ) print(res.json())
Bash
bash
Copy code
curl -X POST https://api.correctics.com/v1/validate \ -H "Content-Type: text/calendar" \ --data-binary @event.ics
9. When to Use UTC vs Local Time
Use UTC when:
-
event times are not tied to human experience (e.g., system reminders)
-
avoiding DST drift is critical
-
you don’t want VTIMEZONE complexity
Use Local time when:
-
event occurs “at 9am local time” no matter what
-
it matters to the user’s physical location
-
the event repeats weekly/monthly
Example: classes, shifts, recurring meetings.
10. Should You Ever Use Floating Times?
Floating times (no TZID, no Z) are almost never correct unless the event:
-
isn’t tied to any specific time zone
-
is purely conceptual (“wake-up time”, “goal deadline”)
Most apps treat floating times inconsistently → avoid unless you deeply know what you’re doing.
11. Summary — Time Zones Are the #1 ICS Failure Point
ICS time zone issues are:
-
extremely common
-
subtle
-
inconsistent across clients
-
easy to break
-
hard to debug manually
To recap:
-
Use valid IANA TZIDs
-
Add VTIMEZONE blocks when required
-
Prefer UTC where appropriate
-
Avoid floating times
-
Always validate ICS files programmatically
For reliable ICS generation, ingestion, or export flows:
👉 Validate and fix files instantly using CorrectICS
👉 Use the API for CI, ingestion, or large-scale automation