How to import a CSV schedule to Google Calendar without shifted times
Google Calendar accepts CSV and .ics files. CSV works for a handful of simple events; for rosters, timetables and anything that crosses a clock change, an .ics with a time zone is the safer route. Here is how both work and where they go wrong.
Route 1
Google’s own CSV format
Google Calendar’s CSV import expects specific English header names in the first row. Only Subject and Start Date are required; every other column is optional. Header names are matched exactly, so “Title” or “Shift” in place of Subject is ignored and the import fails.
| Header | Required | Example | Notes |
|---|---|---|---|
Subject | Yes | Day shift — ER | Event title |
Start Date | Yes | 11/02/2026 | Read in the format of your Google account’s language setting |
Start Time | No | 7:00 AM | Blank means all-day |
End Date | No | 11/02/2026 | Needed for multi-day events |
End Time | No | 3:00 PM | An overnight shift needs the next day’s date in End Date |
All Day Event | No | False | True or False |
Description | No | Triage lead | Free text |
Location | No | ER, Building B | Free text |
Private | No | True | True or False |
There is no time-zone column and no repeat-rule column. Every time in the file is placed in the time zone of the calendar you import into, and repeating classes have to be typed out as separate rows. If your sheet already uses different headers, the CSV to ICS converter matches them automatically and writes an .ics instead.
The common trap
Why events move by an hour
A spreadsheet stores “9:00 AM” with no zone. Google reads it in the calendar’s zone at import time. If the calendar is set to another zone, or the file was produced as UTC by another tool, every event shifts. Clock changes add a second trap: the same 9:00 AM local shift is a different UTC instant before and after the change.
| 9:00 AM New York on | Offset | Same instant in UTC | Seen in London |
|---|---|---|---|
| Fri, Mar 6, 2026 | UTC-5 | 14:00 UTC | 14:00 |
| Mon, Mar 9, 2026 | UTC-4 | 13:00 UTC | 13:00 |
| Fri, Oct 30, 2026 | UTC-4 | 13:00 UTC | 13:00 |
| Mon, Nov 2, 2026 | UTC-5 | 14:00 UTC | 14:00 |
The table is calculated from the time-zone database in this site’s converter. Note late October: New York is still on daylight time while London has already moved back, so the gap between the two cities is four hours for a week instead of five. A file written as fixed UTC times gets those weeks wrong unless it was generated with the right zone rules.
An .ics written with DTSTART;TZID=America/New_York:20261102T090000 and a matching VTIMEZONE block avoids both problems: the event says which zone its wall-clock time belongs to, and Google converts correctly for anyone viewing it from elsewhere.
Route 2
Importing an .ics into Google Calendar
- Create a separate calendarSettings › Add calendar › Create new calendar. Name it after the roster or term so the whole import can be removed by deleting that calendar.
- Convert and checkDrop your sheet on the converter, check the calendar and the problem list, then download the .ics. Try the one-event test file first if you are unsure.
- ImportSettings › Import & export › Import. Choose the .ics, pick the new calendar under “Add to calendar”, select Import.
- Spot-checkOpen a week and compare three events with the sheet, including one overnight shift and one after a clock change.
Imports into Google Calendar are one-off copies: editing the spreadsheet later does not update the calendar. When the rota changes, re-import the new file into the same calendar. Because this converter derives each event’s UID from its content, unchanged shifts are recognised and not duplicated; changed shifts appear as new events, so deleting and recreating the dedicated calendar is the cleanest way to publish a heavily edited version.
Troubleshooting
Import messages and what they mean
| Symptom | Likely cause | Fix |
|---|---|---|
| “Imported 0 out of 0 events” | Header names not recognised, or the file is not UTF-8 CSV | Use Google’s headers exactly, or import an .ics instead |
| Events one hour off after March or November | Times written as fixed UTC or without a zone | Write TZID + VTIMEZONE; pick the sheet’s real zone |
| Events on the wrong day (3 April instead of 4 March) | Day-first dates read month-first | Use YYYY-MM-DD, or set Date order to day-first |
| Night shifts end before they start | End Date missing for shifts past midnight | Add End Date, or let the converter roll them over |
| Duplicates after re-importing | New random UIDs on every export | Use stable UIDs, or import into a fresh calendar |
| Everyone sees everyone’s shifts | One shared file for the whole team | Split the roster into one file per person |
For a team, the last row matters most. Sending the whole rota to everyone fills calendars with other people’s shifts. The schedule CSV to ICS page previews one calendar per person, and the RFC 5545 field reference lists every property the files contain. Coming from Outlook instead? Its CSV wizard asks you to map each column by hand, so the .ics route is also the faster one there.