martes, 16 de noviembre de 2010

iCalendar (II)

En la entrada anterior sobre iCalendar, trate de explicar los principales elementos de un archivo iCalendar, en esta entrada explicare como describir eventos periódicos.

Eventos periódicos

Los eventos periódicos son eventos que no poseen una fecha de inicio o final concreta, si no una regla descriptiva. Este tipo de eventos la mayoría de las veces son explicados de formas como “este evento se repite el tercer sábado de cada mes”, “el evento X se repite cada 4 días 10 veces” o “el eventos se repite el ultimo día de la semana de cada mes”. Si desea ver un ejemplo mas claro de esto, trate de crear un evento periódico en Google Calendar (aqui tiene una explicación de como hacerlo) y si desea ver muchas mas opciones (pero no todas) de iCalendar le recomiendo que lo haga en MS Outlook.

Este tipo de eventos se declaran en iCalendar con la propiedad RRULE del componente VEVENT, a esta propiedad se le debe añadir la información de frecuencia de la regla, en función de la frecuencia deberemos suministrar días, meses, intervalos, etc. Veamos uno ejemplo para poder entenderlo mejor

RRULE:FREQ=DAILY;COUNT=10;INTERVAL=4

Con esta regla estamos indicando que este evento posee una frecuencia diaria (FREQ), con intervalo (INTERVAL) de 4 días (note que el intervalo esta en función del tipo de frecuencia, el valor por defecto es 1) y se repetirá 10 veces (note la propiedad COUNT).

Veamos otro ejemplo esta vez crearemos una repetición de tipo semanal

DTSTART:19970902T090000
RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z

En esta regla estamos indicando una frecuencia semanal que inicia el 02/09/1997 09:00 y termina el (UNTIL) 24/12/1997 00:00
Esta regla se ejecutara los días:

2, 9, 16, 23 y 30 de septiembre
7,14, 21 y 28 de octubre
4, 11, 18 y 25 de noviembre
2,9,16 y 23 de diciembre

Los tipos de frecuencia que se puede indicar en la propiedad RRULE son:

  1. SECONDLY: Utilizado para repeticiones con intervalos de segundos
  2. MINUTELY: Utilizado para repeticiones con intervalos de minutos
  3. HOURLY: Utilizado para repeticiones con intervalos de horas
  4. DAILY: Utilizado para repeticiones con intervalos de días
  5. WEEKLY: Utilizado para repeticiones con intervalos semanales
  6. MONTHLY: Utilizado para repeticiones con intervalos mensuales
  7. YEARLY: Utilizado para repeticiones con intervalos anuales


Según la frecuencia que indique tendrá que suministrar una información u otra, por lo que si desea profundizar en este tema lea la sección 4.3.10 del RFC2445.

Modificaciones de instancias en eventos periódicos

En el apartado anterior explicamos como declarar eventos periódicos en un iCalendar, este tipo de eventos a pesar de declarar un solo evento generan varios eventos (instancias de eventos) que pertenecen a la definición de la periodicidad, dichas instancias pueden sufrir modificaciones en sus propiedades, cuando esto ocurre debemos indicar las propiedades que se modifican y sobre que instancia o instancias de eventos se deben aplicar.

Tomemos la ultima periodicidad de ejemplo:

DTSTART:19970902T090000
RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z

Recodemos que esta periodicidad generaba las siguientes instancias de eventos:

2, 9, 16, 23 y 30 de septiembre
7,14, 21 y 28 de octubre
4, 11, 18 y 25 de noviembre
2,9,16 y 23 de diciembre

Ahora imagine que el usuario desea pasar la instancia de evento que se ejecuta el 16 de septiembre al 15 de septiembre del mismo año, en nuestro archivo iCalendar debemos especificar ese cambio creando una nueva definición de evento (un componente VEVENT) indicando que instancia de la periodicidad sustituye. Veamos un ejemplo:

BEGIN:VEVENT
...
UID:
SEQUENCE:
DTSTART:19970902T090000
RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z
END:VEVENT
(Definimos la periodicidad)


BEGIN:VEVENT
...
UID:
SEQUENCE:
RECURRENCE-ID:19970916T090000//Fecha de la instancia que se modifica
DTSTART:19970915T090000 //La nueva fecha de la instancia
END:VEVENT
(Declaramos la modificación de una instancia)

En este ejemplo el primer evento declara la periodicidad, con la regla de repetición que se debe aplicar y en la segunda definición de evento se indica, que el evento sustituye a la instancia con fecha 16/09/1997 de la periodicidad que posee el identificador y numero de revisión indicados por las propiedades UID y SEQUENCE respectivamente.

Eliminar instancias en eventos periódicos

Para eliminar una o varias instancias de un evento periódico, solo tenemos que indicar las fechas separadas por comas en la propiedad EXDATE del componente VEVENT donde declaramos la definición de la repetición.

Volvamos a tomar el ejemplo anterior, pero esta vez no modificaremos la instancia de fecha 16 de septiembre sino que la eliminaremos.

BEGIN:VEVENT
...
UID:
SEQUENCE:
DTSTART:19970902T090000
RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z
EXDATE:19970915T090000
END:VEVENT

martes, 9 de noviembre de 2010

iCalendar (I)

iCalendar es un estándar para el intercambio de información de eventos, tareas y reuniones de calendarios, el estándar está descrito en el RFC2445 y se complementa con el RFC2446.

En el RFC2445 se detalla la manera cómo se debe plasmar la información de eventos, tareas y reuniones para que puedan ser interpretados por igual en distintos clientes de calendarios; gracias a esto, Google Calendar puede interpretar los calendarios de iCal y viceversa.

Como se pueden imaginar, analizar de manera detallada estos documentos en un blog es una locura, por eso, en esta serie de artículos sólo hablaré sobre el RFC2445.

Antes de empezar, me gustaría aclarar la diferencia de 2 conceptos que aparecen mucho en el RFC2445: “componente” y “propiedades; Las diferencias entre estos dos conceptos son muy simples:

  1. Un componente puede anidar otros componentes.
  2. Un componente puede contener propiedades.
  3. Los componentes inician con el prefijo BEGIN y terminan con el prefijo END

ejemplo:

BEGIN:
...
END:

Bueno, comencemos con el componente raíz de un iCalendar.
Componente VCALENDAR

Es el elemento raíz de un iCalendar. En él, se describen las características de un calendario como pueden ser la zona horaria, la versión del estándar iCalendar utilizado, el identificador del productor (PRODID), etc..

Los propiedades más importantes son:

  1. PROID : Especifica el ID del programa que ha producido el iCalendar, el formato de esta propiedad suele ser “-//NOMBRE_EMPRESA/IDENTIFICADOR_APP//EN”, si desea una mejor explicación y esta dispuesto a pagar por ella lea la ISO_9070.
  2. VERSION: Especifica la versión de iCalendar utilizada, el valor “2.0” es el valor utilizado por el RFC2445.
  3. CALSCALE : Indica el tipo de calendario, “GREGORIAN” es el valor por defecto e indica que el calendario es de tipo gregoriano.
  4. X-WR-CALNAME: No es una propiedad estándar (las propiedades y componentes no estándar empiezan con el prefijo “X-”) pero es utilizada por MS Outlook y Google Calendar para indicar el nombre del calendario.

De los componentes de iCalendar, el componente VCALENDAR es uno de los mas sencillos, con dar valor a estas propiedades ud ya ha suministrado la información mínima para que un cliente iCalendar pueda entender la información de los eventos, tareas y reuniones que puede contener un componente VCALENDAR.

Ejemplo:

BEGIN:VCALENDAR
PRODID:-//Acme company//Acme Calendar x.y.z//EN
VERSION:2.0
CALSCALE:GREGORIAN
X-WR-CALNAME:Nombre de calendario
...
END:VCALENDAR


NOTA: Existen iniciativas que utilizan el estándar iCalendar para realizar otras operaciones distintas al intercambios de eventos, por ejemplo, tzurl.org utiliza el componente VCALENDAR para suministrar información actualizada sobre las zonas horarias mundo.

Componente VEVENT

Es un componente contenido dentro de un VCALENDAR, la finalidad de este componente es suministrar información de un evento, como pude ser el lugar, la fecha y hora de inicio y final, lógica de repetición, etc...

Las propiedades mas importantes:

  1. SUMMARY: Descripción corta del evento (esta información es suministrada por el usuario en una aplicación de calendario).
  2. UID: Identificador único del evento dentro del calendario
  3. TZID: Identificador de la zona horaria.
  4. CREATED: Fecha en la que fue creado el evento (no confundir con la fecha del evento)
  5. LAST-MODIFIED:Fecha de la ultima molificación de este evento.
  6. DESCRIPTION: Descripción del evento (esta información es suministrada por el usuario en una aplicación de calendario).
  7. DTSTART: Fecha/Hora en la que se produce el evento, por defecto se debe suministrar el valor de fecha/hora en el formato UTC que se describe en el ISO 8601
  8. DTEND:Fecha/Hora o en la que se produce el evento, por defecto se debe suministrar el valor de fecha/hora en el formato UTC que se describe en el ISO 8601
  9. SEQUENCE: Numero de revisión del evento, es un secuencial que describe las modificaciones que se realizan sobre el evento

Ejemplo de un evento simple:

BEGIN:VEVENT
SUMMARY:Evento simple
UID:ACME-02882072aecb5d3012aeccadYYYYYYY
SEQUENCE:0
TZID:Europe/Madrid
CREATED:20100831T220000Z
LAST-MODIFIED:20100831T220000Z
DESCRIPTION:Comentario del evento
LOCATION:Lugar
DTSTART:20100901T172200
DTEND:20100901T185200
END:VEVENT

En este ejemplo se define un evento con zona horaria “Europe/Madrid” y el evento inicia el 01/09/2010 17:22 y termina el 01/09/2010 18:52

Eventos de todo el día

Los eventos de todo el día se debe indicar solo la fecha de inicio (DTSTART) con un valor de fecha, con un ejemplo se entiende mejor

BEGIN:VEVENT
DTSTAMP:20100907T152733Z
SUMMARY:Evento todo el dia
UID:ACME-402882072aecb5d3012aeccf00XXXXX
SEQUENCE:0
TZID:Europe/Madrid
CREATED:20100906T220000Z
LAST-MODIFIED:20100906T220000Z
DESCRIPTION:Todo el dia ocupado
DTSTART;VALUE=DATE:20100907
END:VEVENT

Este es un ejemplo de un evento marcado como todo el día, la diferencia con el ejemplo anterior es muy sutil, este tipo de eventos no posee fecha de finalización (DTEND) y en su fecha de inicio (DTSTART) solo se indica la fecha de la forma DTSTART;VALUE=DATE:yyyymmdd.