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
| Column | iCalendar property | Notes |
|---|---|---|
| SUMMARY | SUMMARY | The event title |
| DTSTART | DTSTART | Written as YYYY-MM-DD HH:MM |
| DTEND | DTEND | Exclusive — see all-day events below |
| LOCATION | LOCATION | Often empty; video links usually live in the description |
| DESCRIPTION | DESCRIPTION | Line breaks are flattened into spaces |
| UID | UID | Globally 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:VEVENTThree 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 Z — 20260312T190000Z — 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:20260313This 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
VEVENTwith aRECURRENCE-ID, so it *does* get a row. A series can therefore produce two or three rows without you doing anything wrong. EXDATElists 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:
- Add a client column with a formula matching keywords in SUMMARY
- Filter out rows whose times read
00:00— those are all-day markers, not worked hours - 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
| Symptom | Cause | Fix |
|---|---|---|
| "No events found" | The file has no VEVENT blocks — it may be a subscription URL or a to-do list export | Open it in a text editor and check for BEGIN:VEVENT |
| Events are missing entirely | Outlook exported with limited availability, or the export was date-bounded | Re-export with Full details and a wider range |
| Every time is off by the same amount | The file stores UTC and you're reading local | Add the offset in a spreadsheet column |
| Descriptions run together | Line breaks are flattened into spaces | Expected; split on a known delimiter if you need structure |
| Only a handful of rows for a year of meetings | Recurring series stored once each | Expand the RRULE as described above |
Ready to convert your files?
Free, unlimited, no signup. Your data never leaves your browser.
Related articles
How to Convert CSV to QBO for QuickBooks Online (Free, Any Bank)
Step-by-step guide to converting any bank CSV export into a QBO file for QuickBooks Online — with ba…
CSV to IIF: Import Transactions to QuickBooks Desktop
The QuickBooks Desktop side of a CSV to IIF import: preparing the file, matching account names to yo…