← All articles
Calendar Tools

Convert ICS Calendar to CSV: Complete Guide

February 7, 2026

Billing a client for the meetings you had with them last quarter is a calendar problem pretending to be an accounting problem. The events are all sitting in your calendar with exact start and end times; the only thing standing between you and a timesheet is that calendars export as ICS, and nothing in a spreadsheet can read ICS.

Getting the ICS file out

Google Calendar exports every calendar at once. Open Settings (the gear icon) > Import & export > Export. You get a .zip; unzip it and you'll find one .ics per calendar, named after the calendar's address. To export a single calendar instead, open that calendar's own settings from the left sidebar and use Export calendar there.

Apple Calendar exports one calendar at a time. Select it in the sidebar, then File > Export > Export and save the .ics.

Outlook (classic desktop) uses File > Save Calendar, then More Options to set the date range and level of detail — the default is limited availability, which strips subjects and locations, so choose Full details. Outlook's Import/Export wizard is a separate feature that exports CSV directly; if that CSV has the columns you need, skip the conversion entirely.

Then upload the file to the ICS to CSV converter and download the result.

What ends up in the CSV

ColumniCalendar propertyNotes
SUMMARYSUMMARYThe event title
DTSTARTDTSTARTWritten as YYYY-MM-DD HH:MM
DTENDDTENDExclusive — see all-day events below
LOCATIONLOCATIONOften empty; video links usually live in the description
DESCRIPTIONDESCRIPTIONLine breaks are flattened into spaces
UIDUIDGlobally unique per event, useful for deduplication

Attendees, organiser, and status aren't included — but they're in the raw ICS, which is plain text you can open in any editor.

What an ICS file actually looks like

Each event is a VEVENT block between BEGIN and END markers:

BEGIN:VEVENT
UID:4f8b2c1a-9d3e@example.com
DTSTART;TZID=America/New_York:20260312T140000
DTEND;TZID=America/New_York:20260312T150000
SUMMARY:Client review - Acme
LOCATION:Zoom
RRULE:FREQ=WEEKLY;BYDAY=WE;COUNT=12
END:VEVENT

Three things are worth noticing. The property name can carry parameters after a semicolon (TZID here). Long values wrap onto continuation lines that begin with a single space. And RRULE describes a repeating series without listing any of its occurrences.

Timezones: what the times in your CSV mean

ICS stores times three ways. A value ending in Z20260312T190000Z — is UTC. A value with a TZID parameter is local to that named zone. A bare value with neither is "floating": whatever the local clock says, wherever you are.

The converter writes the time as it appears in the file, without shifting it. That's the right default — a 2pm meeting stays 2pm — but it means a file exported in UTC will show 19:00 for that same 2pm Eastern meeting. Check one event you remember clearly against the CSV before you trust the whole column. If the times are uniformly offset, add or subtract the constant in a spreadsheet column rather than editing the ICS.

Google Calendar exports typically use TZID for timed events. Files generated by scripts and booking tools far more often use UTC.

All-day events end a day late

An all-day event is written as a date with no time, and its DTEND is exclusive — it points at the day after the event finishes. A single all-day event on 12 March looks like this:

DTSTART;VALUE=DATE:20260312
DTEND;VALUE=DATE:20260313

This is correct per the iCalendar spec, not a bug, but it means naive duration arithmetic makes every all-day event one day too long. When you calculate durations in the spreadsheet, subtract a day from all-day rows — they're easy to spot because their times are 00:00.

Recurring events appear once, not weekly

This surprises everyone. A weekly meeting that ran for twelve weeks is stored as one VEVENT carrying an RRULE, so it converts to one CSV row dated to the first occurrence. The other eleven were never in the file — they're generated on the fly by whatever app displays the calendar.

Two related wrinkles:

  • A single modified occurrence (moved, renamed, or cancelled) is stored as its own VEVENT with a RECURRENCE-ID, so it *does* get a row. A series can therefore produce two or three rows without you doing anything wrong.
  • EXDATE lists occurrences deleted from the series. Those dates never appear at all.

To bill a recurring series, read the RRULE and expand it yourself. FREQ=WEEKLY;BYDAY=WE;COUNT=12 means twelve Wednesdays from the start date; UNTIL=20260601T000000Z means repeat until that date instead of a fixed count. A spreadsheet column that fills dates at a weekly interval handles this in about a minute. If most of your calendar is recurring, expand the series inside the calendar app first — printing or exporting a date-bounded view forces the occurrences to materialise.

Turning the CSV into a timesheet

With DTSTART and DTEND as real datetimes, duration is just =(DTEND-DTSTART)*24 formatted as a number, giving decimal hours. From there:

  1. Add a client column with a formula matching keywords in SUMMARY
  2. Filter out rows whose times read 00:00 — those are all-day markers, not worked hours
  3. Pivot by client and by week to get billable hours

If those hours end up as an invoice you then need to book, the accounting-side converters take over: CSV to QBO for QuickBooks Online, CSV to IIF for Desktop.

When something looks wrong

SymptomCauseFix
"No events found"The file has no VEVENT blocks — it may be a subscription URL or a to-do list exportOpen it in a text editor and check for BEGIN:VEVENT
Events are missing entirelyOutlook exported with limited availability, or the export was date-boundedRe-export with Full details and a wider range
Every time is off by the same amountThe file stores UTC and you're reading localAdd the offset in a spreadsheet column
Descriptions run togetherLine breaks are flattened into spacesExpected; split on a known delimiter if you need structure
Only a handful of rows for a year of meetingsRecurring series stored once eachExpand the RRULE as described above

Ready to convert your files?

Free, unlimited, no signup. Your data never leaves your browser.