CorrectICS

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 TZID actually 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