# iCalendar: el formato iCal para tus calendarios digitales

Con iCalendar, cualquier persona puede combinar sus citas procedentes de distintos programas en un único formato. Estas citas pueden gestionarse y modificarse como archivos en un formato estándar. Al tratarse de un estándar global, prácticamente cualquiera puede trabajar con este tipo de archivos.

## iCalendar: definición y explicación del formato de intercambio de datos

iCalendar es un **formato de intercambio de calendarios para la distribución de elementos del calendario**, estandarizado en la [RFC 5545](https://tools.ietf.org/html/rfc5545 "Solicitud de comentarios 5545"). Gracias a este formato es posible consolidar, gestionar y compartir citas procedentes de diferentes aplicaciones en PC y smartphones dentro de un único calendario. El formato se basa en vCalendar, creado en 1998. Con el formato iCal es posible gestionar y compartir de manera práctica **todas las citas de distintas aplicaciones de calendario** en un formato uniforme y casi en tiempo real.

Consejo Los datos de un archivo iCalendar no se limitan a fechas o citas. También permite organizar listas de tareas o programar reuniones.

## ¿Qué es iCal?

Según el sistema operativo, los archivos iCalendar pueden utilizar distintas extensiones, por lo que muchas personas se preguntan qué significan iCal, ICS o iFBF cuando reciben uno de estos archivos. En todos los casos se trata de extensiones del formato iCalendar: [.ics](https://www.ionos.es/digitalguide/correo-electronico/cuestiones-tecnicas/abrir-archivos-ics/), .ifb, .ical y .ifbf hacen referencia a archivos en formato iCal, aunque con algunas diferencias.

- **.ical**: extensión de archivo utilizada en macOS
- **.ics**: extensión de archivo empleada en la mayoría de sistemas operativos
- **.ifb**: extensión estándar para información de disponibilidad (libre/ocupado)
- **.ifbf**: variante utilizada en algunos sistemas macOS como identificador de archivos de disponibilidad (libre/ocupado)

Si deseas enviar un evento, debes seleccionar el **tipo de archivo del formato iCalendar** para guardarlo y enviarlo correctamente. Crear un **archivo ICS (.ics)** suele ser la mejor opción, ya que este formato es compatible con la mayoría de los sistemas operativos. Al abrir el archivo, la persona destinataria puede decidir si acepta o no el evento recibido.

Hecho Los archivos iCalendar son, en esencia, archivos de texto plano, lo que facilita su intercambio entre diferentes sistemas.

## Las ventajas de iCalendar

iCalendar no se limita al simple intercambio de archivos. El formato que utiliza para representar eventos está estrechamente vinculado al estándar de correo electrónico, ya que sigue la especificación Multipurpose Internet Mail Extension (MIME) y, en concreto, el tipo “text/calendar”. Gracias a este diseño abierto, las entradas del calendario en este formato pueden integrarse prácticamente en cualquier contexto, incluso **insertarse en páginas web** para compartir eventos o publicar citas importantes. Junto con servidores [WebDAV](https://www.ionos.es/digitalguide/servidores/know-how/webdav/), utilizados para poner archivos a disposición a través de Internet, es posible sincronizar los eventos en cualquier momento.

Además, el formato permite intercambiar eventos directamente **a través de Bluetooth o mediante una red personal** entre dispositivos móviles. De este modo, si durante una reunión de trabajo deseas fijar la próxima cita, puedes enviar esa entrada a todos los asistentes de forma sencilla. iCalendar también hace posible utilizar la información guardada en varias aplicaciones, que se sincroniza en tiempo real gracias al propio formato.

El formato iCalendar es **compatible con los programas de calendario más utilizados**, que integran los datos del calendario disponibles en la web:

- Google Calendar
- Calendario de Android
- Microsoft Outlook
- Calendario de BlackBerry
- Calendario de macOS/iOS

## ¿Qué significa la normalización mediante RFC 5545?

RFC 5545 define cómo deben estructurarse y codificarse los datos de calendario para que puedan ser leídos y procesados correctamente por diferentes aplicaciones.

El elemento central es una estructura de datos unificada basada en los llamados componentes del calendario, como `VEVENT`, `VTODO`, `VJOURNAL` o `VTIMEZONE`. Cada uno de estos componentes sigue una estructura claramente definida con campos obligatorios y opcionales que incluyen propiedades específicas, como la hora de inicio, la hora de fin, el lugar o la descripción de un evento.

Además, RFC 5545 regula otras propiedades, como:

- la **sintaxis** (formato de texto UTF-8, longitud de línea, saltos de línea),
- los **formatos de fecha y hora** (incluidas las zonas horarias) y
- la **codificación de eventos recurrentes**, por ejemplo mediante la propiedad `RRULE`.

Así se garantiza que un archivo .ics se interprete siempre del mismo modo, independientemente del programa o del sistema operativo utilizado.

## Cómo crear un archivo iCal paso a paso

De la teoría a la práctica. **Crear una cita** funciona del siguiente modo:

1. Abre un documento nuevo en un editor de texto de tu elección. Con la aplicación adecuada, esto también puede hacerse desde un smartphone.
2. A continuación, rellena el archivo siguiendo el esquema estándar de iCalendar, que te explicaremos con más detalle en el siguiente paso.
3. Cuando finalices el documento, expórtalo en formato iCalendar. Para ello, guarda el archivo con la extensión “.ics”.
4. Abre un programa de calendario de tu elección e importa el archivo .ics como evento. Solo tendrás que hacer clic en el menú correspondiente, y el evento se cargará automáticamente desde el directorio.
5. El evento aparecerá ahora como una entrada en tu calendario.

Para que la transferencia de datos funcione correctamente y la persona destinataria pueda importar el evento en su propio calendario, debes transmitir la información en un formato predeterminado. Cada línea tiene un significado concreto:

<table>
  <thead>
    <tr>
      <th>Línea iCal</th>
      <th>Significado</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>`BEGIN:VCALENDAR`</td>
      <td>Señala el inicio de cualquier archivo iCalendar.</td>
    </tr>
    <tr>
      <td>`VERSION`</td>
      <td>Aquí se especifica la versión del formato, actualmente “2.0”.</td>
    </tr>
    <tr>
      <td>`PRODID`</td>
      <td>Indica el nombre o la dirección de quien crea el archivo o de la aplicación utilizada.</td>
    </tr>
    <tr>
      <td>`METHOD`</td>
      <td>Define el tipo de transmisión: con `PUBLISH`, la entrada aparece inmediatamente; con `REQUEST`, envías el evento como solicitud.</td>
    </tr>
    <tr>
      <td>`BEGIN:VEVENT`</td>
      <td>Marca el inicio de la sección que contiene los datos relevantes del evento.</td>
    </tr>
    <tr>
      <td>`UID`</td>
      <td>Cada entrada de calendario en un archivo .ics necesita un identificador único.</td>
    </tr>
    <tr>
      <td>`LOCATION`</td>
      <td>Indica el lugar del evento, con el nivel de detalle que desees.</td>
    </tr>
    <tr>
      <td>`SUMMARY`</td>
      <td>Proporciona un breve resumen del evento.</td>
    </tr>
    <tr>
      <td>`DESCRIPTION`</td>
      <td>Añade una descripción detallada que solo se muestra al abrir la entrada del evento.</td>
    </tr>
    <tr>
      <td>`CLASS`</td>
      <td>Determina si el evento se guarda como público (`PUBLIC`) o privado (`PRIVATE`).</td>
    </tr>
    <tr>
      <td>`DTSTART`</td>
      <td>Indica la hora de inicio del evento.</td>
    </tr>
    <tr>
      <td>`DTEND`</td>
      <td>Indica la hora de fin del evento.</td>
    </tr>
    <tr>
      <td>`DTSTAMP`</td>
      <td>Muestra la marca de tiempo en la que se creó la entrada del calendario.</td>
    </tr>
    <tr>
      <td>`END:VEVENT`</td>
      <td>Finaliza la sección con la información del evento.</td>
    </tr>
    <tr>
      <td>`END:VCALENDAR`</td>
      <td>Cierra el archivo.</td>
    </tr>
  </tbody>
</table>

Los horarios también siguen un formato estandarizado:

- Las primeras cuatro cifras indican el **año** (YYYY): **2019**
- Las dos siguientes, el **mes** (MM): 2019**10**
- Las dos últimas, el **día** (DD): 201910**27**
- La letra **T** separa la fecha de la hora: 20191027**T**

La hora se compone de 6 cifras:

- dos para la **hora**: 20191027T**15**
- dos para el **minuto**: 20191027T15**59**
- dos para los **segundos**: 20191027T1559**54**
- la entrada se cierra con una **Z**: 20191027T155954**Z**

En el siguiente ejemplo, todas las líneas están completadas correctamente:

```txt
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Cal_App//Daily@Planet
METHOD:PUBLISH
BEGIN:VEVENT
UID:123456789@ejemplo.com
LOCATION:Madrid
SUMMARY:Reunión
DESCRIPTION:Reunión de lanzamiento
CLASS:PUBLIC
DTSTART:20191101T100000Z
DTEND:20191101T120000Z
DTSTAMP:20191027T155954Z
END:VEVENT
END:VCALENDAR
```

Al abrir el archivo, la persona receptora puede añadir automáticamente el evento a su calendario y acceder a toda la información relevante, desde el tipo de evento hasta la hora de inicio y finalización. Así, el formato iCalendar supone un auténtico ahorro de tiempo, especialmente en el ámbito laboral.

## Incorporar iCalendar en el frontend

En lugar de crear un archivo ICS, también puedes redirigir a los usuarios mediante **URL especiales** directamente a un proveedor de calendario en línea, como Google Calendar, Outlook.com o Yahoo Calendar. Estos enlaces abren una nueva ventana de **“Añadir evento”** en el navegador del servicio correspondiente, ya completada con la información relativa al título, lugar, descripción y hora de inicio y fin.

```html
<a href="https://calendar.google.com/calendar/render?action=TEMPLATE
&amp;text=Release%20Meeting
&amp;details=Status-Update%20%26%20Milestones
&amp;location=Remote%20(Google%20Meet)
&amp;dates=20251010T080000Z/20251010T090000Z
&amp;ctz=Europe/Madrid"
target="_blank" rel="noopener">
Añadir a Google Calendar
</a>
```

## Generar archivos .ics por código

A continuación encontrarás ejemplos prácticos que muestran cómo crear archivos ICS con apenas unas líneas de código. Todos los ejemplos generan un evento llamado “Reunión de lanzamiento” para el **15/10/2025**, de **10:00 a 11:00 (Europa/Madrid)**, con finales de línea correctos (CRLF) y escape básico de caracteres.

### Ejemplo en PHP

En este ejemplo de PHP, primero se define la función auxiliar `ics_escape()`. Su objetivo es asegurar que caracteres especiales como comas, puntos y comas, barras invertidas o saltos de línea se **escapen correctamente**. A continuación, se crea la estructura del archivo ICS en un array, donde cada línea representa un atributo del evento, como el título (`SUMMARY`), la descripción (`DESCRIPTION`) o el periodo (`DTSTART`, `DTEND`). La instrucción `implode("\r\n", [...])` une todas las líneas en un único bloque de texto.

Después, se utilizan dos comandos `header()` que indican al navegador cómo debe tratar el archivo:

- `Content-Type: text/calendar; charset=utf-8` indica que se trata de un archivo de calendario en formato iCalendar.
- `Content-Disposition: attachment; filename="event.ics"` indica que el archivo no debe mostrarse directamente en el navegador, sino descargarse automáticamente con el nombre indicado.

Finalmente, `echo $ics` envía el archivo ensamblado al navegador. Al abrir el script PHP (por ejemplo, `event.php`), se iniciará automáticamente la descarga de **event.ics**, que podrá importarse de inmediato en Outlook, Google Calendar o Apple Calendar.

```php
function ics_escape($s) {
    return str_replace(
        ["\\",    ";",    ",",    "\n"],
        ["\\\\","\\;", "\\,", "\\n"],
        $s
    );
}
$ics = implode("\r\n", [
    "BEGIN:VCALENDAR",
    "PRODID:-//example.com//ics-php//ES",
    "VERSION:2.0",
    "CALSCALE:GREGORIAN",
    "METHOD:PUBLISH",
    "BEGIN:VEVENT",
    "UID:event-123@ejemplo.com",
    "DTSTAMP:20251010T080000Z",
    "DTSTART;TZID=Europe/Madrid:20251015T100000",
    "DTEND;TZID=Europe/Madrid:20251015T110000",
    "SUMMARY:" . ics_escape("Release-Meeting"),
    "DESCRIPTION:" . ics_escape("Status-Update & Milestones"),
    "LOCATION:" . ics_escape("Remote (Google Meet)"),
    "END:VEVENT",
    "END:VCALENDAR",
    ""
]);
header('Content-Type: text/calendar; charset=utf-8');                // Informa al navegador: "Este es un archivo .ics"
header('Content-Disposition: attachment; filename="event.ics"'); // Inicia la descarga
echo $ics; // Envía el texto al navegador
```

### Ejemplo en Python

Aquí también, la función `ics_escape()` asegura que los caracteres especiales como comas, punto y coma o saltos de línea se enmascaren correctamente. Con `datetime.now(timezone.utc)` se crea automáticamente una marca de tiempo actual (`DTSTAMP`) en formato UTC. Las líneas individuales del evento, como el título (`SUMMARY`), se unen luego en un bloque de texto con `"\r\n".join([...])`. Los saltos de línea CRLF (`\r\n`) siguen siendo obligatorios en el formato ICS.

El comando `Path("event-python.ics").write_text(ics, encoding="utf-8", newline="")` finalmente escribe el contenido como un archivo UTF-8 en el directorio actual. Después de ejecutar el script, el archivo final `event-python.ics` está listo y puede importarse de inmediato en Outlook, Google Calendar o Apple Calendar.

```python
from datetime import datetime, timezone
from pathlib import Path
def ics_escape(s: str) -> str:
    return s.replace("\\", "\\\\").replace(";", "\\;").replace(",", "\\,").replace("\n", "\\n")
ics = "\r\n".join([
    "BEGIN:VCALENDAR",
    "PRODID:-//example.com//ics-python//ES",
    "VERSION:2.0",
    "CALSCALE:GREGORIAN",
    "METHOD:PUBLISH",
    "BEGIN:VEVENT",
    "UID:event-123@ejemplo.com",
    f"DTSTAMP:{datetime.now(timezone.utc):%Y%m%dT%H%M%SZ}",
    "DTSTART;TZID=Europe/Madrid:20251015T100000",
    "DTEND;TZID=Europe/Madrid:20251015T110000",
    f"SUMMARY:{ics_escape('Release-Meeting')}",
    f"DESCRIPTION:{ics_escape('Status-Update & Milestones')}",
    f"LOCATION:{ics_escape('Remote (Google Meet)')}",
    "END:VEVENT",
    "END:VCALENDAR",
    ""
])
Path("event-python.ics").write_text(ics, encoding="utf-8", newline="")
print("Archivo creado: event-python.ics")
```

### Ejemplo en JavaScript

El siguiente código JavaScript genera el contenido del calendario directamente en el navegador. Primero, el texto del iCalendar se ensambla en la variable `ics`. La función `icsEscape()` garantiza nuevamente que caracteres especiales como comas o saltos de línea se enmascaren correctamente. Mediante `Blob()`, se crea en memoria un archivo virtual a partir del texto, y `URL.createObjectURL()` genera una URL de descarga temporal que el navegador interpreta como si fuera un archivo real.

A continuación, se crea dinámicamente un elemento `<a>` invisible con el atributo `download`, que se activa automáticamente mediante `a.click()`. De este modo, la descarga del archivo `event-browser.ics` se inicia sin necesidad de una conexión con el servidor.

```javascript
<button id="dl">Descargar .ics</button>
<script>
function icsEscape(s) {
    return s
        .replace(/\\/g, "\\\\")
        .replace(/;/g, "\\;")
        .replace(/,/g, "\\,")
        .replace(/\n/g, "\\n");
}
const ics = [
    "BEGIN:VCALENDAR",
    "PRODID:-//example.com//ics-browser//ES",
    "VERSION:2.0",
    "CALSCALE:GREGORIAN",
    "METHOD:PUBLISH",
    "BEGIN:VEVENT",
    "UID:event-123@ejemplo.com",
    "DTSTAMP:20251010T080000Z",
    "DTSTART;TZID=Europe/Madrid:20251015T100000",
    "DTEND;TZID=Europe/Madrid:20251015T110000",
    "SUMMARY:" + icsEscape("Release-Meeting"),
    "DESCRIPTION:" + icsEscape("Status-Update & Milestones"),
    "LOCATION:" + icsEscape("Remote (Google Meet)"),
    "END:VEVENT",
    "END:VCALENDAR",
    ""
].join("\r\n");
document.getElementById("dl").addEventListener("click", () => {
    const blob = new Blob([ics], { type: "text/calendar;charset=utf-8" }); // Crear objeto de archivo
    const url = URL.createObjectURL(blob); // URL de descarga temporal
    const a = document.createElement("a");
    a.href = url;
    a.download = "event-browser.ics"; // Nombre del archivo descargado
    document.body.appendChild(a);
    a.click(); // Inicia la descarga
    a.remove();
    URL.revokeObjectURL(url); // Liberar la URL temporal
});
</script>
```

### Ejemplo en Node.js

Este código inicia un pequeño servidor web Express que pone a disposición un archivo .ics directamente desde el navegador. Cuando alguien accede a `http://localhost:3000/event.ics`, el manejador `app.get(...)` genera el texto del iCalendar y lo envía al cliente. La función `icsEscape()` garantiza, como en los ejemplos anteriores, que los caracteres especiales se enmascaren correctamente. Con `res.setHeader("Content-Type", "text/calendar; charset=utf-8")`, el servidor informa al navegador de que se trata de un archivo de calendario. El encabezado `Cache-Control: public, max-age=300` permite almacenar el archivo en caché durante 5 minutos. Por último, `res.send(ics)` envía el archivo generado directamente al navegador, que lo descargará automáticamente o lo abrirá con la aplicación de calendario configurada. El servidor se ejecuta localmente en `http://localhost:3000/event.ics`.

```javascript
import express from "express";
const app = express();
function icsEscape(s) {
    return s
        .replace(/\\/g, "\\\\")
        .replace(/;/g, "\\;")
        .replace(/,/g, "\\,")
        .replace(/\n/g, "\\n");
}
app.get("/event.ics", (req, res) => {
    const ics = [
        "BEGIN:VCALENDAR",
        "PRODID:-//example.com//ics-node//ES",
        "VERSION:2.0",
        "CALSCALE:GREGORIAN",
        "METHOD:PUBLISH",
        "BEGIN:VEVENT",
        "UID:event-123@ejemplo.com",
        "DTSTAMP:20251010T080000Z",
        "DTSTART;TZID=Europe/Madrid:20251015T100000",
        "DTEND;TZID=Europe/Madrid:20251015T110000",
        "SUMMARY:" + icsEscape("Reunión de lanzamiento"),
        "DESCRIPTION:" + icsEscape("Actualización de estado e hitos"),
        "LOCATION:" + icsEscape("Remoto (Google Meet)"),
        "END:VEVENT",
        "END:VCALENDAR",
        ""
    ].join("\r\n");
    res.setHeader("Content-Type", "text/calendar; charset=utf-8"); // El navegador reconoce el tipo MIME
    res.setHeader("Cache-Control", "public, max-age=300");                 // Caché (5 minutos)
    res.send(ics); // Enviar archivo ICS
});
app.listen(3000, () =>
    console.log("http://localhost/event.ics")
);
```

## Archivos .ics en diferentes clientes de calendario

Aunque iCalendar es un estándar abierto, cada aplicación de calendario interpreta los archivos ICS a su manera. Según el sistema, pueden existir diferencias en la forma en que los eventos se importan, se sincronizan y se actualizan.

### Google Calendar

En Google Calendar, los usuarios pueden importar archivos .ics manualmente o suscribirse a un feed de calendario mediante una URL.

Al importar un archivo ICS, los eventos incluidos se transfieren **una sola vez** al calendario seleccionado. Los cambios que realices posteriormente en el archivo almacenado en tu servidor **no se actualizarán automáticamente**. Google trata esta opción como una instantánea.

La **suscripción por URL** funciona de manera diferente y solo está disponible en la versión web de Google Calendar. Para ello, seleccionas “Otros calendarios” &gt; “Añadir por URL” e introduces la dirección de un archivo ICS, por ejemplo: `https://ejemplo.com/calendario.ics`. Google recupera este archivo de forma periódica (normalmente cada 12 a 24 horas) y actualiza los eventos si se han producido cambios.

Es importante destacar que Google **no acepta** enlaces `webcal://`. Por lo tanto, si deseas ofrecer un enlace de suscripción en tu página web, deberás utilizar siempre la versión **HTTPS** de la URL.

### Calendario de Apple

El Calendario de Apple admite el formato iCalendar (.ics) de forma especialmente completa y cómoda. Cuando los usuarios descargan un archivo ICS o lo abren desde un correo electrónico, el sistema lo reconoce automáticamente y pregunta en qué calendario deben importarse los eventos. También en este caso se trata de una **importación única**, que **no se actualiza automáticamente** posteriormente.

Mucho más potente es la **función de suscripción**, que Apple admite directamente a través del esquema `webcal://`. Por lo tanto, si en tu página web incluyes un enlace como `webcal://ejemplo.com/calendario.ics`, al hacer clic se abrirá automáticamente el diálogo de calendario que pregunta si se desea suscribir a él. Un calendario suscrito de este modo se **sincroniza automáticamente**, por defecto cada pocas horas. Los cambios en eventos existentes (misma `UID`, nuevo `DTSTAMP`) se incorporan correctamente, y las entradas eliminadas desaparecen en la siguiente actualización.

### Outlook

Microsoft Outlook permite tanto **importar archivos ICS de forma puntual** como **suscribirse a ellos**. Si abres un archivo ICS con doble clic o lo importas manualmente, Outlook añade los eventos contenidos al calendario seleccionado. Estos eventos son estáticos, de modo que los cambios posteriores en el servidor **no se reflejarán** en Outlook.

La opción de **suscripción** funciona de forma similar a la del Calendario de Apple: los usuarios pueden introducir la URL del feed desde “Abrir calendario” &gt; “Desde Internet” (por ejemplo, `https://ejemplo.com/calendario.ics` o también `webcal://...`). Outlook se suscribe a este calendario y lo sincroniza automáticamente a intervalos regulares. Normalmente, este intervalo oscila entre 30 minutos y 3 horas, aunque en algunos casos puede ser más largo.

Outlook.com —la versión web— funciona de manera similar desde el punto de vista técnico, aunque a veces actualiza los datos con mayor retraso que la aplicación de escritorio.


This is a markdown version of: [https://www.ionos.es/digitalguide/paginas-web/desarrollo-web/icalendar/](https://www.ionos.es/digitalguide/paginas-web/desarrollo-web/icalendar/) for AI/LLM consumption.