Outlook calendar shows the wrong time zone in Google Calendar
You subscribed to an Outlook or Microsoft 365 .ics link in Google Calendar,
and every event landed at the wrong hour โ usually shifted to GMT/UTC. Here is why, and a free fix
that corrects the time zone without moving your meetings.
The fix: Outlook publishes its feed using Microsoft's own time zone names, like
TZID=W. Europe Standard Time. Google Calendar only understands standard
IANA names like
Europe/Berlin, so when the feed also omits a matching VTIMEZONE definition,
Google cannot resolve the zone and falls back to UTC. Run the feed through a proxy that rewrites those
names to their IANA equivalents, then subscribe to the proxy URL instead of the Outlook URL.
Nothing about the event times changes โ only the label Google reads.
Generate your corrected feed URL
Subscribe to this URL in Google Calendar:
What the proxy found in your feed:
Free, no account, no ads. The proxy fetches your feed on demand and rewrites the time zone labels in transit โ it stores no calendar data and keeps no copy of your events.
How to add the corrected feed to Google Calendar
- Get your Outlook link. In Outlook on the web, go to Settings โ Calendar โ Shared calendars, publish the calendar you want, choose Can view all details, and copy the ICS link โ not the HTML one.
- Paste it into the box above and press Generate link.
- Copy the generated URL.
- Open Google Calendar on a computer. The web UI is required โ you cannot add a feed URL from the mobile apps.
- In the left sidebar, click + next to Other calendars โ From URL.
- Paste the generated URL and click Add calendar.
If you already subscribed to the raw Outlook link, remove that subscription first. Google will not update the time zone handling of an existing subscription; you need to unsubscribe and add the corrected URL as a new one.
Why Outlook feeds land in UTC: what is actually in the file
An .ics feed states each event's time and, separately, which time zone that time is in.
RFC 5545 โ the iCalendar standard โ allows a TZID to be any string, on the condition
that the file also contains a VTIMEZONE component defining what that string means.
Microsoft names its zones the Windows way:
BEGIN:VEVENT
DTSTART;TZID=W. Europe Standard Time:20260810T100000
DTEND;TZID=W. Europe Standard Time:20260810T110000
SUMMARY:Weekly sync
END:VEVENT
Google Calendar resolves zones against the IANA time zone database, where that zone is called
Europe/Berlin. W. Europe Standard Time is not in it. If the feed ships a
well-formed VTIMEZONE block, Google can still work out the offsets from it. When it does
not โ and Microsoft's published feeds frequently do not, or ship one that does not match the
TZID actually used on the events โ Google has an unresolvable zone and does the only
safe thing left: it treats the time as UTC. In Berlin in summer that is your meeting two hours early.
The corrected feed says the same thing in a vocabulary Google shares:
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20260810T100000
DTEND;TZID=Europe/Berlin:20260810T110000
SUMMARY:Weekly sync
END:VEVENT
The digits 20260810T100000 are identical. Only the label changed. That distinction is
the whole point, and it is where the naive version of this fix goes wrong โ see below.
Why "just set the time zone to mine" is the wrong fix
Several tools and scripts offer to force every event into a time zone you pick. Overwriting
TZID=Europe/Berlin with TZID=Asia/Shanghai does not convert
10:00 Berlin into the correct Shanghai time. It relabels it as 10:00 Shanghai, moving the
meeting six hours โ and because every event still looks plausible, nobody notices until someone misses
a call. This tool refuses to do that. The time zone selector above is a fallback: it is applied
only to events that carry no zone at all, where some assumption has to be made and there is no correct
answer to destroy.
Which Windows zone names get mapped
All 139 of them, from the
Unicode CLDR
windowsZones.xml mapping โ the same table Microsoft points developers at for translating
between the two systems. A hand-written list of the dozen common zones is the usual reason a fix works
for colleagues in Berlin and fails for the one in Kathmandu.
| Windows name written by Outlook | IANA name Google understands |
|---|---|
GMT Standard Time | Europe/London |
W. Europe Standard Time | Europe/Berlin |
Romance Standard Time | Europe/Paris |
Central Europe Standard Time | Europe/Budapest |
Eastern Standard Time | America/New_York |
Pacific Standard Time | America/Los_Angeles |
China Standard Time | Asia/Shanghai |
India Standard Time | Asia/Kolkata |
AUS Eastern Standard Time | Australia/Sydney |
Note that GMT Standard Time means UK time including British Summer
Time, not GMT. Microsoft's naming is a large part of why this problem exists.
Find out what is wrong with your feed before you fix it
Add &debug=1 to the generated URL, or press Diagnose my feed above, and you
get a JSON report instead of a calendar: which time zone names the feed uses, which VTIMEZONE
blocks it defines, which names were rewritten and to what, and which could not be resolved at all.
{
"zonesFound": ["W. Europe Standard Time"],
"vtimezonesDefined": [],
"rewrittenZones": [
{ "from": "W. Europe Standard Time", "to": "Europe/Berlin", "via": "cldr-windows-zone" }
],
"unresolvedZones": [],
"allDayTzidStripped": 0
}
If zonesFound is empty and your events still show at the wrong time, the time zone is not
your problem โ see feed won't load or
not updating.
Alternatives, and when each one is better
| Approach | Fixes the time zone? | Cost | Worth it when |
|---|---|---|---|
| This proxy | Yes, and keeps each event's own zone | Free, no account | You just want the subscription to be right and you are fine relying on a third-party URL. |
| Deploy the same worker yourself | Identical โ same code | Free tier, ~5 minutes | The calendar is work-sensitive and you would rather no one else's domain sat in the path. |
| Change the time zone in Outlook's settings | No | Free | Never, for this symptom โ Outlook still writes Windows zone names whatever you set. |
Download the .ics and import it once |
Sometimes โ Google's importer is more forgiving than its subscriber | Free | It is a one-off calendar that will never change. Imported events do not sync. |
| Force all events into one zone (many scripts do this) | No โ it silently shifts events, see above | Free | Only if every event genuinely is in that one zone. |
| A paid sync service (OnePlaceMail, Calendar Bridge, etc.) | Yes, plus two-way sync and faster refresh | Subscription | You need edits to flow both ways, or refresh faster than Google's polling allows. |
When this will not fix it
- Every event is off by a whole day, not a few hours. That is the all-day event bug โ see all-day events on the wrong day.
- Times are right but changes take hours to appear. That is Google's polling interval, not a time zone problem โ see Outlook calendar not updating.
- The calendar is empty, or Google says it could not fetch the URL. See feed won't load.
- Only some events are wrong. Usually events created in a different zone, or by an
external organiser whose own client wrote a broken
VTIMEZONE. Run the diagnosis โ ifunresolvedZonesis non-empty, that is what you are looking at. - You need to edit events from Google and have them appear in Outlook. An ICS subscription is read-only by design. No proxy can change that.
Questions
Why does my Outlook calendar show GMT in Google Calendar?
Because the published .ics feed labels its events with Windows time zone names such as
GMT Standard Time or Central Europe Standard Time, which are not IANA
identifiers. When Google Calendar cannot resolve the zone and the feed does not define it in a
VTIMEZONE block, it falls back to treating the times as UTC.
Does the fix change the actual event times?
No. It rewrites the time zone name attached to each event and leaves the clock time exactly
as Outlook wrote it. An event at 10:00 in W. Europe Standard Time comes out as 10:00 in
Europe/Berlin โ the same instant, now expressed in a vocabulary Google understands.
Is it safe to route my calendar through a third-party URL?
Be deliberate about it. The proxy has to fetch your feed, so anyone holding the generated URL can read that calendar โ exactly as anyone holding the raw Outlook publish link already can. The proxy stores nothing and logs no calendar content, but you are still adding a party to the path. If the calendar is sensitive, deploy the worker to your own Cloudflare account: it is a single file, the source is public, and the free tier covers a calendar subscription many times over.
Do I have to pay, or sign up?
No. There is no account, no payment and no ad. Google Calendar polls a subscribed feed a handful of times a day, which sits far inside Cloudflare's free tier.
Will this work for Apple Calendar, Thunderbird or Fastmail?
Yes. The output is a standard iCalendar feed; nothing about the repair is Google-specific. Apple Calendar in particular is stricter than Google about malformed feeds, so it benefits from the same fix.
How often does the corrected feed update?
The proxy caches for 15 minutes and otherwise fetches live, so it is never the bottleneck. Your refresh rate is whatever Google Calendar decides, typically every 8 to 24 hours for external feeds. See not updating for what you can do about that.
My time zone is not in the dropdown.
The dropdown only sets the fallback for zoneless events, and most people should leave it on
None. If you do need one that is not listed, add &tz=Area/City to the
generated URL using any IANA identifier โ the proxy accepts all of them.
Other calendar feed problems
- Outlook calendar not updating in Google Calendar New and changed events take 8โ24 hours to appear, or never do.
- All-day events land on the wrong day Birthdays and out-of-office days shifted one day earlier or later.
- The ICS feed won't load at all Empty calendar, "could not fetch the URL", or an HTTP 400 from the subscriber.