An .ics file is a calendar event written as plain text. Double-click it and
your calendar app imports it, which may be the one thing you didn't want to do
yet. You can see the time first, in your own zone, and everything else in it.
An Outlook invitation, in its own time zone and the reader's.
Select the .ics file in Finder and press Space. Quick Look previews the
event without importing it. Its calendar previewer reads the title, the start
and end, the location and the guests, and gives the times in your Mac's time
zone (checked on macOS 26.5).
For a repeating meeting it shows the first date only. Read on if the meeting repeats and the organiser is in another country.
How a file writes a time
The time is on the DTSTART line (and DTEND for the end). It comes in three
forms, and each means something different:
DTSTART:20261021T143000Z
DTSTART;TZID=America/New_York:20261015T100000
DTSTART:20261024T193000
| Form | Example | What it means |
|---|---|---|
UTC, ends in Z |
20261021T143000Z |
14:30 UTC. One moment, shown in your own time (16:30 in Amsterdam) |
TZID= a zone |
TZID=America/New_York:…T100000 |
10:00 on a New York wall clock, whatever the date's offset is there |
| Neither (floating) | 20261024T193000 |
19:30 wherever you are. The file doesn't tie it to a place |
A date with VALUE=DATE and no time (DTSTART;VALUE=DATE:20261024) is an
all-day event: the same date in every zone.
The TZID form is the one invitations use, and the one that goes wrong. The
name can be a standard zone (America/New_York) or whatever the sending app
calls it: Outlook writes Windows names such as W. Europe Standard Time. Either
way, the rules for that zone (its offsets and when its clocks change) should be
in a VTIMEZONE block near the top of the same file, which
RFC 5545 requires for
every TZID a file uses. A floating time is
defined as local time
for whoever reads it, which is fine for a dinner and wrong for a call between
two countries.
Read it as text
Any text editor opens an .ics. To pull out just the lines that matter, on a
Mac or Linux:
sed -n '/^BEGIN:VEVENT/,/^END:VEVENT/p' invite.ics | grep -E '^(SUMMARY|DTSTART|DTEND|RRULE|LOCATION)'
On an Outlook invitation, that prints:
SUMMARY;LANGUAGE=en-US:Quarterly planning review
DTSTART;TZID=W. Europe Standard Time:20261021T093000
DTEND;TZID=W. Europe Standard Time:20261021T110000
LOCATION;LANGUAGE=en-US:Room 4.12 (8)
The sed part keeps the event and skips the VTIMEZONE block, which has
DTSTART and RRULE lines of its own (dated 1601, in Outlook's case). To see
the zone's rules, look at that block:
grep -A4 '^BEGIN:DAYLIGHT' invite.ics
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
That is UTC+2 from the last Sunday in March: Central European time, so this meeting is 09:30 in Berlin, Amsterdam or Paris.
iCalendar wraps lines at 75 bytes and starts each continuation with a space, so
a long ATTENDEE or DESCRIPTION line is split across several lines of the
file. The time lines are short enough that this rarely touches them.
Convert the time with one command
date does the conversion. Set TZ to your zone, and tell it which zone the
file's time is in.
On a Mac (BSD date), read the time in the event's zone, then print it in
yours:
TZ=Europe/Amsterdam date -r $(TZ=America/New_York date -j -f %Y%m%dT%H%M%S 20261015T100000 +%s)
Thu Oct 15 16:00:00 CEST 2026
For a Z time, read it as UTC: TZ=UTC date -j -f %Y%m%dT%H%M%SZ 20261021T143000Z +%s
inside the brackets.
On Linux (GNU date), the zone goes inside the date string. GNU date can't
read the compact 20261015T100000 form, so write the date out:
TZ=Europe/Amsterdam date -d 'TZ="America/New_York" 2026-10-15 10:00'
TZ=Europe/Amsterdam date -d '2026-10-21 14:30Z'
Thu Oct 15 16:00:00 CEST 2026
Wed Oct 21 16:30:00 CEST 2026
Or Python, which has the time zone rules built in from 3.9 (the python3 in
Apple's command line developer tools is 3.9):
python3 -c "
from datetime import datetime
from zoneinfo import ZoneInfo
t = datetime(2026, 10, 15, 10, 0, tzinfo=ZoneInfo('America/New_York'))
print(t.astimezone(ZoneInfo('Europe/Amsterdam')))"
2026-10-15 16:00:00+02:00
None of these know Outlook's Windows zone names. For W. Europe Standard Time, use the city its VTIMEZONE describes (Europe/Berlin), or let a viewer
read the block for you.
Repeating meetings and the clocks
A weekly meeting has an RRULE line, and every date in the series is pinned to
the organiser's wall clock. When the organiser's country changes its clocks on a
different day from yours, the meeting moves for you.
This series is 10:00 every Thursday in New York, four times from 15 October 2026:
DTSTART;TZID=America/New_York:20261015T100000
RRULE:FREQ=WEEKLY;BYDAY=TH;COUNT=4
Converting each date with the commands above, for a reader in Amsterdam:
| Thursday | New York | Amsterdam |
|---|---|---|
| 15 Oct | 10:00 EDT | 16:00 CEST |
| 22 Oct | 10:00 EDT | 16:00 CEST |
| 29 Oct | 10:00 EDT | 15:00 CET |
| 5 Nov | 10:00 EST | 16:00 CET |
Europe turned its clocks back on 25 October, the US on 1 November. For the one week in between, the meeting is an hour earlier in Europe. In spring the gap is longer: the US moved forward on 8 March 2026 and Europe on 29 March, so a 10:00 Thursday meeting in New York was at 15:00 in Amsterdam on 12, 19 and 26 March, and back at 16:00 from 2 April.
Your calendar app gets this right once the event is imported. What you can't see from a preview of the first date is that it happens, which is the thing to check before agreeing to a slot that is fine three weeks out of four.
The 29 October date is an hour earlier for a reader in Europe.
Check it in the browser
- Open the Calendar Viewer and drop the
.icson the page, or click Choose file. With no file at hand, Sample invitation opens one set in New York. - The invitation opens as one card. The first time is in the event's own zone, and the line below is your time. The ruler under it lines the two up, and the caption says how far ahead or behind you are.
- To see it in a zone other than your own, click the time zone button above the card and type a city in the search box.
- For a repeating meeting, click Show the dates under Repeats: every date is listed in the zone you chose.
- View source shows the file with line numbers,
DTSTARTincluded. Copy details copies the title, both times, the place and the join link as text.
A time with no zone is labelled as a floating time, and an all-day event as the same date in every zone, so neither looks like a conversion that didn't happen. An Outlook zone name is read as the standard zone it stands for, and the file is read on your device: nothing is uploaded, and no image or link in it is loaded.
When you are happy with it, double-click the file to import it.
If you double-click it
On a Mac, the file goes to Calendar, and on Windows to Outlook or the Calendar
app, whichever owns .ics files. Those apps open the file in order to add it to
a calendar, and with an invitation they may also offer to send your reply to the
organiser. That is fine once you know the time works. If an event went in that
you didn't want, delete it in the app; for a meeting invitation, declining it
tells the organiser, where deleting may not.
Which to use
- One meeting, on a Mac: Quick Look (Space in Finder). It shows the first date in your time and imports nothing.
- A repeating meeting across countries: the Calendar
Viewer, or the
datecommand on each date. Look at March and late October. - Windows, a Chromebook or a phone: the Calendar Viewer. Opening the file anywhere else imports it.
- A file that won't import, or shows the wrong time: read the
DTSTARTlines. A floating time or aTZIDwith noVTIMEZONEblock is the usual cause.