Merge ICS files when several calendar exports have to become one import or one archive. FindUtils Merge ICS reads the .ics files you drop, in the order you drop them, and writes a single VCALENDAR that holds every event, to-do and journal entry they carried. The files are read in the browser and nothing is uploaded.

This guide explains what a calendar export actually gives you, what the merged file keeps and what it rebuilds, how the optional UID dedupe chooses a copy, when the New UIDs option is the right answer, and what happens when one of the files is not a calendar at all.

Why Does a Calendar Export Give You One File per Calendar?

Calendar apps export per calendar and import per file, so a person with six calendars ends up with six files and six import dialogs. Google Calendar's export is a zip holding one .ics for every calendar you own. Apple Calendar exports the calendar you selected in the sidebar, once per calendar. Outlook desktop saves one calendar per file through File > Save Calendar.

That shape is fine while the calendars stay separate and awkward the moment you want one of these:

  • An archive. One searchable file for a calendar you are about to close.
  • A migration. One import into a new account instead of one import per calendar.
  • A team view. Each member's export folded into a single file to share.
  • A backup refresh. An old backup and a fresh export combined, with one copy of each event.

Joining .ics files by hand in a text editor is the usual fallback, and it is where the format bites. iCalendar folds long lines at 75 octets and continues them with a leading space, so a careless paste can break a description into an invalid line, and two copies of the same VTIMEZONE block can be enough for an importer to refuse the whole file.

How Do You Export and Merge the Calendars?

Export each calendar, drop the files in the order you want them, set the options, download.

  1. Export every calendar. Google Calendar: Settings > Import & export > Export, which downloads a zip. Apple Calendar: File > Export > Export, once per calendar. Outlook desktop: File > Save Calendar, with the date range and detail level under More Options.
  2. Unzip the Google export. Merge ICS reads calendar files, not archives, so the .ics files inside the zip have to be unzipped first.
  3. Drop the files on the page. The dropzone takes several at once and accepts .ics, .ical, .ifb and .txt. Up to 20 calendars merge in one pass, and the list keeps the order you added them in.
  4. Set the options. Type a calendar name if you want one, turn on the UID dedupe when the same events appear in more than one export, and turn on New UIDs only when the events have to import as new.
  5. Read the stats line and download. The line under the output reports events in, events out, duplicates removed when the dedupe is on, and time zones. The download is named after the first file's stem, as <name>-merged.ics.

One file on its own is allowed when you only want to dedupe it or rename it, and the page shows a hint asking for at least one more calendar.

What Does the Merged File Contain?

The merged file contains every non-VTIMEZONE child of every input calendar, in file order, with every property it arrived with. VEVENT, VTODO, VJOURNAL, VFREEBUSY and vendor components are all carried, and inside each of them RRULE, EXDATE, nested VALARM blocks, ATTENDEE, DESCRIPTION, LOCATION and X- properties are written exactly as they were read.

VTIMEZONE blocks are the exception, because a definition repeated in five files is still one time zone. Merge ICS writes one VTIMEZONE per TZID and the first one it sees wins. The times themselves are never touched: a DTSTART keeps its TZID parameter or its trailing Z, and no value is converted from one zone into another.

Two things are rewritten on the way out, and both are the format asking for them. Long lines are folded again at 75 octets with CRLF endings, and a parameter value that holds a colon, a semicolon or a comma is written back in quotes, so an organizer such as ORGANIZER;CN="Doe, Jane" survives the round trip. A calendar app reads the result as the same event.

What Header Does the Merged Calendar Get?

The calendar header is the one part Merge ICS rebuilds, because the merged file no longer comes from any single app. The rules below decide each header property.

Header propertyWhat the merged file gets
VERSIONAlways 2.0
PRODIDAlways -//FindUtils//Merge ICS//EN, replacing the PRODID of each source app
CALSCALEThe value every input that states one agrees on, otherwise GREGORIAN
METHODThe value every input that states one agrees on, otherwise PUBLISH
X-WR-CALNAMEThe name you type, else the name every input agrees on, else no name at all
X-WR-TIMEZONEThe hint kept when the inputs agree on it, otherwise omitted

Leaving the name empty when the inputs disagree is deliberate. A merged file with no X-WR-CALNAME makes the calendar app ask you what to call it, which is better than inheriting the name of whichever file happened to be first.

How Does the UID Dedupe Work?

The UID dedupe is off by default, so a plain merge never drops anything on its own. Turn on Remove duplicates by UID and Merge ICS keeps one component per key, where the key is the component kind plus the UID plus the RECURRENCE-ID, including that property's TZID.

The copy that stays is the newest one, decided by LAST-MODIFIED first, then DTSTAMP, then SEQUENCE. When none of those three separate the copies, the first one seen stays. The kept copy sits in the position the first copy held, so deduping never reshuffles the file order you chose when you dropped the calendars.

A component that carries no UID at all cannot be keyed, so the dedupe leaves every such component in the output untouched. The stats line reports how many components the dedupe removed, which is worth reading before you trust the merged file as a complete archive.

Why Is RECURRENCE-ID Part of the Dedupe Key?

RECURRENCE-ID is in the key because a modified occurrence of a recurring meeting shares the UID of its series. When you move one Tuesday standup to Wednesday, the calendar stores a second component with the same UID plus a RECURRENCE-ID naming the occurrence it replaces.

A tool that deduped on UID alone would treat that pair as one duplicate and keep exactly one of them. You would lose either the recurrence rule or the exception, and the loss would be invisible until the series reappeared in the wrong place. Keying on kind plus UID plus RECURRENCE-ID keeps the series master and each of its exceptions as separate keys.

When Should You Turn On New UIDs?

Turn on New UIDs when a calendar app refuses to add the events because it already holds them. A calendar app matches an imported event to an existing one by UID, and a match updates the existing event instead of creating a new one, which is why a re-import can look like it did nothing.

With the option on, every UID becomes a fresh value of the form <8 hex digits>-<n>@findutils.com, where the hex is an FNV-1a hash of the old UID and n numbers the distinct old UIDs in the merge. A recurrence master and its exceptions share one old UID, so they share one new UID and stay a series. A component that arrived without a UID gets one derived from its own serialized text.

The rewrite is deterministic: the same inputs always produce the same new UIDs, so running the merge twice does not create a third set of identifiers. Leave the option off for a plain merge, because rewritten UIDs break the link between the merged file and the events still living in the original calendars.

What Happens When One File Cannot Be Read?

One unreadable file does not stop the merge. Merge ICS reports that file next to its name with a reason and carries on with the rest, so a stray download in the folder costs you a line in the report rather than the whole run.

Four cases are reported this way: an empty input, a text with no BEGIN: line, which is the signature of a file that is not iCalendar at all, a file with no VCALENDAR component, and a calendar that parses but holds no events, to-dos or journal entries. Only when not a single input can be read does the page show an error instead of an output.

Is Anything Uploaded?

No. Merge ICS reads the dropped files with the browser's own file reader, parses and rewrites them in the tab, and hands the result back as a download. No request carries the calendar text, and you can confirm that in the browser's network panel while a merge runs.

The tool also never fetches a calendar URL. It merges the files you give it and nothing else, which matters because a calendar export is a record of who you met, when, and where.

Can You Merge Calendars From a Script?

Yes. The same module runs on the FindUtils API and MCP server as merge_ics, with the REST id merge-ics. Pass the .ics texts as the inputs array, at most 20 of them in the order you want, with the same dedupe_uid, regenerate_uids and calendar_name options the page offers. The response carries the merged calendar in ics, the counts in events_in, events_out, duplicates_removed and timezones, and the per-file report in files.

Common Mistakes

Mistake 1: Dropping the Zip Instead of the Calendars

A Google Calendar export downloads as a zip, and Merge ICS reads calendar files. Unzip it first and drop the .ics files it contains.

Mistake 2: Expecting the Dedupe to Run by Default

Every copy of every event stays unless you turn the UID dedupe on. Check the stats line: events in and events out are equal on a plain merge.

Mistake 3: Turning On New UIDs for a Backup

New UIDs makes the merged file import as a fresh set of events, which is exactly wrong for a backup that should keep matching the calendar it came from. Use it for a deliberate second copy or a refused import.

Mistake 4: Reading the Stats Line as an Event Count Only

Events in and events out count VEVENT components. To-dos and journal entries are merged too and are not part of those two numbers.

Mistake 5: Ignoring the Per-File Report

A skipped file is named with its reason above the output. Read the report before you treat the merged calendar as complete.

Tools Used in This Guide

  • Merge ICS - Several .ics exports into one calendar file.
  • Split ICS - The reverse: one large calendar cut into numbered parts.
  • ICS to JSON - Every event as a JSON object for a script.
  • ICS to CSV - One spreadsheet row per event.
  • CSV to ICS - Rows turned back into an importable calendar.

FAQ

Q1: Does merging edit my events? A: No. Every component is written with the properties it arrived with. The only rewrites are the line folding at 75 octets and the re-quoting of a parameter value that holds a colon, semicolon or comma, both required by the format.

Q2: How many calendars can be merged at once? A: Up to 20 per merge. One file alone is accepted when you only want to dedupe or rename it.

Q3: Can Google, Apple and Outlook exports be merged together? A: Yes. All three write the same RFC 5545 format, so their components are copied side by side. Only the PRODID in the header is replaced; vendor X- properties inside the events stay.

Q4: Why does the merged file have no calendar name? A: Because the inputs carried different names and you did not type one. The merge leaves X-WR-CALNAME out rather than picking a name for you.

Q5: Are recurring events expanded into individual occurrences? A: No. An RRULE is copied as text and stays a rule, and EXDATE values travel with it.

Q6: What order do the events come out in? A: File order, then the order inside each file. Dedupe keeps a component in the place its first copy held, so the order survives that too.

Next Steps

Merge two exports, open the result in a text editor, and check the header and the first event against the original file before you import it anywhere.