Cómo fusionar varios calendarios en un único archivo ICS
Por qué pegar archivos .ics a mano rompe el calendario, qué ocurre con los UID duplicados y las zonas horarias al combinar exportaciones distintas, y qué revisar antes de importar el archivo fusionado.
Fusionar calendarios significa producir un único objeto VCALENDAR válido que contenga todos los VEVENT de los archivos de origen. No es lo mismo que pegar los archivos uno detrás de otro: un archivo ICS tiene exactamente una envoltura BEGIN:VCALENDAR / END:VCALENDAR, un PRODID, un VERSION y un conjunto de definiciones VTIMEZONE que los eventos referencian por nombre. Al concatenar dos exportaciones obtienes un archivo con dos envolturas, y la mayoría de los analizadores o lo rechazan o solo leen hasta el primer END:VCALENDAR, descartando en silencio lo que venga después. Esta guía explica qué ocurre de verdad en una fusión, cómo tratar los duplicados y los conflictos de zona horaria, y qué comprobar en el archivo combinado.
Por qué no basta con concatenar los archivos
La RFC 5545 define un flujo iCalendar como uno o más objetos iCalendar, pero también dice que una aplicación conforme solo está obligada a procesar el primero. En la práctica, Google Calendar, Apple Calendar y Outlook se comportan como si solo hubiera uno. Si ejecutas `cat trabajo.ics personal.ics > todo.ics`, la segunda mitad del resultado o es invisible o provoca un error, según el importador.
Aunque el analizador fuera tolerante, seguiría habiendo tres propiedades en conflicto:
- PRODID identifica el software que generó el calendario. Es obligatoria y debe aparecer una sola vez por VCALENDAR. Dos líneas PRODID en un mismo objeto es un archivo inválido.
- VERSION declara la versión de iCalendar (en la práctica siempre 2.0) y también es obligatoria una única vez. Duplicarla es un error de validación directo.
- CALSCALE, METHOD y propiedades X- como X-WR-CALNAME o X-WR-TIMEZONE son de nivel calendario. Si dos archivos discrepan —uno dice X-WR-TIMEZONE:Europe/Madrid y el otro America/New_York— el importador elige una arbitrariamente y los eventos con hora flotante se desplazan.
Una fusión correcta extrae los componentes VEVENT, VTODO y VJOURNAL de cada origen, conserva una sola cabecera, reúne los bloques VTIMEZONE que los eventos usan y escribe un único objeto. Nuestra herramienta Fusionar archivos ICS hace eso dentro del navegador: sueltas los archivos y recibes un calendario limpio, sin subir nada a ningún servidor.
Eventos duplicados: el problema del UID
UID es el identificador único global de un evento. Dos componentes con el mismo UID no son dos eventos: son el mismo evento, y la versión vigente es la que tenga el SEQUENCE más alto (o el DTSTAMP más reciente cuando el SEQUENCE empata). Esto salta a la vista en el caso que más problemas da: exportar el mismo calendario dos veces, con unas semanas de diferencia, y fusionar ambas exportaciones.
Los eventos de esos dos archivos comparten UID, y lo que ocurre al importar depende de la aplicación. Google Calendar toma el UID como referencia y actualiza la entrada existente en vez de añadir una segunda, así que una fusión ingenua pierde en silencio una de las copias. Apple Calendar suele conservar ambas si el DTSTART difiere. Outlook es el menos previsible y crea duplicados visibles el mismo día.
Mismo evento, UID distinto
El caso contrario es igual de frecuente. Si te invitaron a una reunión en dos cuentas, o el mismo evento se creó por separado en dos calendarios, los UID no coinciden aunque el título, la fecha y el lugar sean idénticos. Ningún importador lo detecta, porque según la especificación son eventos distintos. La deduplicación tiene que comparar SUMMARY junto con DTSTART, no solo el UID. Nuestra herramienta Eliminar eventos duplicados aplica ambos criterios, y el orden habitual es fusionar primero y deduplicar después.
Eventos recurrentes y RECURRENCE-ID
Una instancia modificada de una serie recurrente se guarda como un VEVENT aparte con el mismo UID que el evento maestro más un RECURRENCE-ID que apunta a la aparición original. Si la fusión descarta una de esas excepciones, o conserva la excepción pero pierde el maestro, la serie se queda sin su modificación o no se expande. Nunca dedupliques por UID a secas si el archivo tiene eventos recurrentes: los componentes que comparten UID pero difieren en RECURRENCE-ID tienen que sobrevivir todos.
Qué pasa con las zonas horarias cuando los orígenes no coinciden
Cada evento con hora referencia una zona horaria mediante el parámetro TZID en DTSTART y DTEND, y el calendario debería incluir un componente VTIMEZONE que defina ese identificador. Al fusionar archivos de procedencias distintas aparecen tres fallos típicos.
- Definición ausente: un evento dice TZID=Europe/Madrid pero ningún bloque VTIMEZONE para Europe/Madrid ha llegado al archivo final. Los analizadores estrictos rechazan el evento; los permisivos recurren a la zona del sistema, que es la correcta en tu portátil y la equivocada para cualquier otra persona.
- Definiciones en conflicto: dos archivos definen un VTIMEZONE para el mismo TZID con reglas de horario de verano distintas, por haberse exportado con años de diferencia o con programas distintos. Solo queda una, y los eventos del otro archivo heredan reglas para las que no fueron escritos.
- Identificadores no IANA: las exportaciones de Microsoft usan a menudo nombres como "Romance Standard Time" o "Eastern Standard Time" en lugar de Europe/Madrid o America/New_York. Al fusionar una exportación de Microsoft con una de Google, la mitad de los eventos usan nombres IANA y la otra mitad no. Google Calendar rechaza los nombres de Windows sin más.
Están además el UTC y la hora flotante. Los eventos escritos como DTSTART:20260601T090000Z son absolutos y se fusionan sin ambigüedad. Los escritos como DTSTART:20260601T090000, sin Z y sin TZID, son flotantes: significan las 09:00 de la zona horaria del dispositivo que los lee. Mezclar eventos flotantes de un origen con eventos con zona de otro produce un calendario correcto para quien lo montó y equivocado para el resto. Si algún origen usa horas flotantes, normalízalas antes de fusionar: la herramienta Reparar / Limpiar ICS reescribe los nombres de zona de Windows a identificadores IANA y ancla las horas flotantes a una zona explícita.
Casos reales en los que fusionar es lo correcto
Trabajo y personal en una sola vista
Exportar el calendario de trabajo y el personal y fusionarlos te da un archivo único que puedes importar en un teléfono que solo sincroniza una cuenta, o entregar a una herramienta de planificación que acepta una sola subida. Vigila el solapamiento de UID si ambas cuentas recibieron la misma convocatoria de reunión.
Consolidar calendarios de equipo
Cinco personas exportan sus calendarios, los fusionas y tienes un archivo de disponibilidad conjunta para cargar en una herramienta de planificación o imprimir. Como cada una exporta desde su cuenta, los UID son distintos incluso para la reunión a la que asistieron todas, así que deduplica por título y hora de inicio, no por UID, o esa reunión aparecerá cinco veces.
Preparar un calendario público de eventos
Los tracks de un congreso, los partidos de una liga o los horarios de un curso suelen mantenerse por separado y publicarse juntos. Fusiona los archivos de cada bloque, pon un X-WR-CALNAME con sentido y aloja el resultado en una URL estable para que la gente se suscriba en lugar de importar. Quien se suscribe vuelve a descargar el archivo, así que mantén los UID estables entre publicaciones: si los cambias, cada suscriptor recibe un juego completo de duplicados.
Qué revisar después de fusionar
- El recuento de eventos. Cuenta las líneas BEGIN:VEVENT en los orígenes y en el resultado. Si el total fusionado es menor que la suma, algo se ha descartado o deduplicado: averigua qué.
- Una sola cabecera. Exactamente un BEGIN:VCALENDAR, un END:VCALENDAR, un PRODID y un VERSION.
- Cobertura de zonas horarias. Cada TZID distinto que use algún evento tiene su componente VTIMEZONE correspondiente en el archivo.
- Las series recurrentes. Abre el archivo y confirma que las líneas RRULE siguen ahí y que las excepciones con RECURRENCE-ID conservan su evento maestro.
- Una pasada de validación. Pasa el archivo por Validar ICS antes de importar: marca propiedades obligatorias ausentes, sintaxis RRULE rota y referencias de zona huérfanas con su número de línea.
- Una importación de prueba. Importa primero en un calendario desechable: borrarlo es fácil; separar 300 eventos de tu calendario principal, no.
En resumen
Fusionar calendarios es una operación estructural, no de texto. El archivo necesita una sola envoltura y una sola cabecera, las definiciones de zona horaria deben acompañar a los eventos que las referencian y los duplicados hay que resolverlos por la clave adecuada: el UID en reexportaciones del mismo calendario, el título más la hora de inicio cuando es el mismo evento creado en cuentas distintas. Con eso resuelto, el archivo se importa sin sorpresas.