diff --git a/CHANGES.rst b/CHANGES.rst index d7d1c88f..587b1bfd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -9,6 +9,8 @@ Minor changes: - Added ``end``, ``start``, ``duration``, ``DTSTART``, ``DUE``, and ``DURATION`` attributes to ``Todo`` components. See `Issue 662`_. - Format test code with Ruff. See `Issue 672 `_. - Document the Debian package. See `Issue 701 `_. +- Document ``vDatetime.from_ical`` +- Allow passing a ``datetime.date`` to ``TZP.localize_utc`` and ``TZP.localize`` methods. - Document component classes with description from :rfc:`5545`. Breaking changes: @@ -19,6 +21,13 @@ New features: - Add ``VALARM`` properties for :rfc:`9074`. See `Issue 657 `_ - Test compatibility with Python 3.13 +- Add ``icalendar.alarms`` module to calculate alarm times. See `Issue 716 `_. +- Add ``Event.alarms`` and ``Todo.alarms`` to access alarm calculation. +- Add ``Component.DTSTAMP`` and ``Component.LAST_MODIFIED`` properties for datetime in UTC. +- Add ``Component.is_thunderbird()`` to check if the component uses custom properties by Thunderbird. +- Add ``X_MOZ_SNOOZE_TIME`` and ``X_MOZ_LASTACK`` properties to ``Event`` and ``Todo``. +- Add ``Alarm.ACKNOWLEDGED``, ``Alarm.TRIGGER``, ``Alarm.REPEAT``, and ``Alarm.DURATION`` properties + as well as ``Alarm.triggers`` to calculate alarm triggers. Bug fixes: diff --git a/docs/api.rst b/docs/api.rst index 757f905c..ac211638 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,6 +1,13 @@ API Reference ------------- +icalendar.alarms +++++++++++++++++ + +.. automodule:: icalendar.alarms + :members: + + icalendar.cal +++++++++++++ diff --git a/src/icalendar/__init__.py b/src/icalendar/__init__.py index d0e5f10e..e1a09a02 100644 --- a/src/icalendar/__init__.py +++ b/src/icalendar/__init__.py @@ -1,3 +1,11 @@ +from icalendar.alarms import ( + Alarms, + AlarmTime, + ComponentEndMissing, + ComponentStartMissing, + IncompleteAlarmInformation, + LocalTimezoneMissing, +) from icalendar.cal import ( Alarm, Calendar, @@ -94,4 +102,10 @@ "vMonth", "IncompleteComponent", "InvalidCalendar", + "Alarms", + "AlarmTime", + "ComponentEndMissing", + "ComponentStartMissing", + "IncompleteAlarmInformation", + "LocalTimezoneMissing", ] diff --git a/src/icalendar/alarms.py b/src/icalendar/alarms.py new file mode 100644 index 00000000..e8999d13 --- /dev/null +++ b/src/icalendar/alarms.py @@ -0,0 +1,388 @@ +"""Compute the times and states of alarms. + +This takes different calendar software into account and the RFC 9074 (Alarm Extension). + +- RFC 9074 defines an ACKNOWLEDGED property in the VALARM. +- Outlook does not export VALARM information. +- Google Calendar uses the DTSTAMP to acknowledge the alarms. +- Thunderbird snoozes the alarms with a X-MOZ-SNOOZE-TIME attribute in the event. +- Thunderbird acknowledges the alarms with a X-MOZ-LASTACK attribute in the event. +- Etar deletes alarms that are acknowledged. +- Nextcloud's Webinterface does not do anything with the alarms when the time passes. +""" + +from __future__ import annotations + +from datetime import date, timedelta, tzinfo +from typing import TYPE_CHECKING, Generator, Optional, Union + +from icalendar.cal import Alarm, Event, Todo +from icalendar.timezone import tzp +from icalendar.tools import is_date, normalize_pytz, to_datetime + +if TYPE_CHECKING: + from datetime import datetime + +Parent = Union[Event,Todo] + + +class IncompleteAlarmInformation(ValueError): + """The alarms cannot be calculated yet because information is missing.""" + +class ComponentStartMissing(IncompleteAlarmInformation): + """We are missing the start of a component that the alarm is for. + + Use Alarms.set_start(). + """ + +class ComponentEndMissing(IncompleteAlarmInformation): + """We are missing the end of a component that the alarm is for. + + Use Alarms.set_end(). + """ + +class LocalTimezoneMissing(IncompleteAlarmInformation): + """We are missing the local timezone to compute the value. + + Use Alarms.set_local_timezone(). + """ + + +class AlarmTime: + """An alarm time with all the information.""" + + def __init__( + self, + alarm: Alarm, + trigger : datetime, + acknowledged_until:Optional[datetime]=None, + snoozed_until:Optional[datetime]=None, + parent: Optional[Parent]=None, + ): + """Create a new AlarmTime. + + alarm + the Alarm component + + trigger + a date or datetime at which to trigger the alarm + + acknowledged_until + an optional datetime in UTC until when all alarms + have been acknowledged + + snoozed_until + an optional datetime in UTC until which all alarms of + the same parent are snoozed + + parent + the optional parent component the alarm refers to + + local_tzinfo + the local timezone that events without tzinfo should have + """ + self._alarm = alarm + self._parent = parent + self._trigger = trigger + self._last_ack = acknowledged_until + self._snooze_until = snoozed_until + + @property + def acknowledged(self) -> Optional[datetime]: + """The time in UTC at which this alarm was last acknowledged. + + If the alarm was not acknowledged (dismissed), then this is None. + """ + ack = self.alarm.ACKNOWLEDGED + if ack is None: + return self._last_ack + if self._last_ack is None: + return ack + return max(ack, self._last_ack) + + @property + def alarm(self) -> Alarm: + """The alarm component.""" + return self._alarm + + @property + def parent(self) -> Optional[Parent]: + """This is the component that contains the alarm. + + This is None if you did not use Alarms.set_component(). + """ + return self._parent + + def is_active(self) -> bool: + """Whether this alarm is active (True) or acknowledged (False). + + For example, in some calendar software, this is True until the user looks + at the alarm message and clicked the dismiss button. + + Alarms can be in local time (without a timezone). + To calculate if the alarm really happened, we need it to be in a timezone. + If a timezone is required but not given, we throw an IncompleteAlarmInformation. + """ + acknowledged = self.acknowledged + if not acknowledged: + # if nothing is acknowledged, this alarm counts + return True + if self._snooze_until is not None and self._snooze_until > acknowledged: + return True + trigger = self.trigger + if trigger.tzinfo is None: + raise LocalTimezoneMissing( + "A local timezone is required to check if the alarm is still active. " + "Use Alarms.set_local_timezone()." + ) + return trigger > acknowledged + + @property + def trigger(self) -> date: + """This is the time to trigger the alarm. + + If the alarm has been snoozed, this can differ from the TRIGGER property. + """ + if self._snooze_until is not None and self._snooze_until > self._trigger: + return self._snooze_until + return self._trigger + + +class Alarms: + """Compute the times and states of alarms. + + This is an example using RFC 9074. + One alarm is 30 minutes before the event and acknowledged. + Another alarm is 15 minutes before the event and still active. + + >>> from icalendar import Event, Alarms + >>> event = Event.from_ical( + ... '''BEGIN:VEVENT + ... CREATED:20210301T151004Z + ... UID:AC67C078-CED3-4BF5-9726-832C3749F627 + ... DTSTAMP:20210301T151004Z + ... DTSTART;TZID=America/New_York:20210302T103000 + ... DTEND;TZID=America/New_York:20210302T113000 + ... SUMMARY:Meeting + ... BEGIN:VALARM + ... UID:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 + ... TRIGGER:-PT30M + ... ACKNOWLEDGED:20210302T150004Z + ... DESCRIPTION:Event reminder + ... ACTION:DISPLAY + ... END:VALARM + ... BEGIN:VALARM + ... UID:8297C37D-BA2D-4476-91AE-C1EAA364F8E1 + ... TRIGGER:-PT15M + ... DESCRIPTION:Event reminder + ... ACTION:DISPLAY + ... END:VALARM + ... END:VEVENT + ... ''') + >>> alarms = Alarms(event) + >>> len(alarms.times) # all alarms including those acknowledged + 2 + >>> len(alarms.active) # the alarms that are not acknowledged, yet + 1 + >>> alarms.active[0].trigger # this alarm triggers 15 minutes before 10:30 + datetime.datetime(2021, 3, 2, 10, 15, tzinfo=ZoneInfo(key='America/New_York')) + + RFC 9074 specifies that alarms can also be triggered by proximity. + This is not implemented yet. + """ + + def __init__(self, component:Optional[Alarm|Event|Todo]=None): + """Start computing alarm times.""" + self._absolute_alarms : list[Alarm] = [] + self._start_alarms : list[Alarm] = [] + self._end_alarms : list[Alarm] = [] + self._start : Optional[date] = None + self._end : Optional[date] = None + self._parent : Optional[Parent] = None + self._last_ack : Optional[datetime] = None + self._snooze_until : Optional[datetime] = None + self._local_tzinfo : Optional[tzinfo] = None + + if component is not None: + self.add_component(component) + + def add_component(self, component:Alarm|Parent): + """Add a component. + + If this is an alarm, it is added. + Events and Todos are added as a parent and all + their alarms are added, too. + """ + if isinstance(component, (Event, Todo)): + self.set_parent(component) + self.set_start(component.start) + self.set_end(component.end) + if component.is_thunderbird(): + self.acknowledge_until(component.X_MOZ_LASTACK) + self.snooze_until(component.X_MOZ_SNOOZE_TIME) + else: + self.acknowledge_until(component.DTSTAMP) + + for alarm in component.walk("VALARM"): + self.add_alarm(alarm) + + def set_parent(self, parent: Parent): + """Set the parent of all the alarms. + + If you would like to collect alarms from a component, use add_component + """ + if self._parent is not None and self._parent is not parent: + raise ValueError("You can only set one parent for this alarm calculation.") + self._parent = parent + + def add_alarm(self, alarm: Alarm) -> None: + """Optional: Add an alarm component.""" + trigger = alarm.TRIGGER + if trigger is None: + return + if isinstance(trigger, date): + self._absolute_alarms.append(alarm) + elif alarm.TRIGGER_RELATED == "START": + self._start_alarms.append(alarm) + else: + self._end_alarms.append(alarm) + + def set_start(self, dt: Optional[date]): + """Set the start of the component. + + If you have only absolute alarms, this is not required. + If you have alarms relative to the start of a compoment, set the start here. + """ + self._start = dt + + def set_end(self, dt: Optional[date]): + """Set the end of the component. + + If you have only absolute alarms, this is not required. + If you have alarms relative to the end of a compoment, set the end here. + """ + self._end = dt + + def _add(self, dt: date, td:timedelta): + """Add a timedelta to a datetime.""" + if is_date(dt): + if td.seconds == 0: + return dt + td + dt = to_datetime(dt) + return normalize_pytz(dt + td) + + def acknowledge_until(self, dt: Optional[date]) -> None: + """This is the time in UTC when all the alarms of this component were acknowledged. + + Only the last call counts. + + Since RFC 9074 (Alarm Extension) was created later, + calendar implementations differ in how they acknowledge alarms. + For example, Thunderbird and Google Calendar store the last time + an event has been acknowledged because of an alarm. + All alarms that happen before this time count as acknowledged. + """ + self._last_ack = tzp.localize_utc(dt) if dt is not None else None + + def snooze_until(self, dt: Optional[date]) -> None: + """This is the time in UTC when all the alarms of this component were snoozed. + + Only the last call counts. + + The alarms are supposed to turn up again at dt when they are not acknowledged + but snoozed. + """ + self._snooze_until = tzp.localize_utc(dt) if dt is not None else None + + def set_local_timezone(self, tzinfo:Optional[tzinfo|str]): + """Set the local timezone. + + Events are sometimes in local time. + In order to compute the exact time of the alarm, some + alarms without timezone are considered local. + + Some computations work without setting this, others don't. + If they need this information, expect a LocalTimezoneMissing exception + somewhere down the line. + """ + self._local_tzinfo = tzp.timezone(tzinfo) if isinstance(tzinfo, str) else tzinfo + + @property + def times(self) -> list[AlarmTime]: + """Compute and return the times of the alarms given. + + If the information for calculation is incomplete, this will raise a + IncompleteAlarmInformation exception. + + Please make sure to set all the required parameters before calculating. + If you forget to set the acknowledged times, that is not problem. + """ + return ( + self._get_end_alarm_times() + + self._get_start_alarm_times() + + self._get_absolute_alarm_times() + ) + + def _repeat(self, first: datetime, alarm: Alarm) -> Generator[datetime]: + """The times when the alarm is triggered relative to start.""" + yield first # we trigger at the start + repeat = alarm.REPEAT + duration = alarm.DURATION + if repeat and duration: + for i in range(1, repeat + 1): + yield self._add(first, duration * i) + + def _alarm_time(self, alarm: Alarm, trigger:date): + """Create an alarm time with the additional attributes.""" + if getattr(trigger, "tzinfo", None) is None and self._local_tzinfo is not None: + trigger = normalize_pytz(trigger.replace(tzinfo=self._local_tzinfo)) + return AlarmTime(alarm, trigger, self._last_ack, self._snooze_until, self._parent) + + def _get_absolute_alarm_times(self) -> list[AlarmTime]: + """Return a list of absolute alarm times.""" + return [ + self._alarm_time(alarm , trigger) + for alarm in self._absolute_alarms + for trigger in self._repeat(alarm.TRIGGER, alarm) + ] + + def _get_start_alarm_times(self) -> list[AlarmTime]: + """Return a list of alarm times relative to the start of the component.""" + if self._start is None and self._start_alarms: + raise ComponentStartMissing("Use Alarms.set_start because at least one alarm is relative to the start of a component.") + return [ + self._alarm_time(alarm , trigger) + for alarm in self._start_alarms + for trigger in self._repeat(self._add(self._start, alarm.TRIGGER), alarm) + ] + + def _get_end_alarm_times(self) -> list[AlarmTime]: + """Return a list of alarm times relative to the start of the component.""" + if self._end is None and self._end_alarms: + raise ComponentEndMissing("Use Alarms.set_end because at least one alarm is relative to the end of a component.") + return [ + self._alarm_time(alarm , trigger) + for alarm in self._end_alarms + for trigger in self._repeat(self._add(self._end, alarm.TRIGGER), alarm) + ] + + @property + def active(self) -> list[AlarmTime]: + """The alarm times that are still active and not acknowledged. + + This considers snoozed alarms. + + Alarms can be in local time (without a timezone). + To calculate if the alarm really happened, we need it to be in a timezone. + If a timezone is required but not given, we throw an IncompleteAlarmInformation. + """ + return [alarm_time for alarm_time in self.times if alarm_time.is_active()] + +__all__ = [ + "Alarms", + "AlarmTime", + "IncompleteAlarmInformation", + "ComponentEndMissing", + "ComponentStartMissing", + "LocalTimezoneMissing" +] diff --git a/src/icalendar/cal.py b/src/icalendar/cal.py index c01925ce..8522d24f 100644 --- a/src/icalendar/cal.py +++ b/src/icalendar/cal.py @@ -7,15 +7,20 @@ import os from datetime import date, datetime, timedelta -from typing import List, Optional, Tuple +from typing import TYPE_CHECKING, List, NamedTuple, Optional, Tuple, Union import dateutil.rrule import dateutil.tz + from icalendar.caselessdict import CaselessDict from icalendar.parser import Contentline, Contentlines, Parameters, q_join, q_split from icalendar.parser_tools import DEFAULT_ENCODING -from icalendar.prop import TypesFactory, vDDDLists, vDDDTypes, vText, vDuration +from icalendar.prop import TypesFactory, vDDDLists, vDDDTypes, vDuration, vText from icalendar.timezone import tzp +from icalendar.tools import is_date + +if TYPE_CHECKING: + from icalendar.alarms import Alarms def get_example(component_directory: str, example_name: str) -> bytes: @@ -76,9 +81,45 @@ class IncompleteComponent(ValueError): The attributes are not required, otherwise this would be an InvalidCalendar. But in order to perform calculations, this attribute is required. + + This error is not raised in the UPPERCASE properties like .DTSTART, + only in the lowercase computations like .start. + """ + +def create_utc_property(name:str, docs:str) -> property: + """Create a property to access a value of datetime in UTC timezone. + + name - name of the property + docs - documentation string """ + docs = f"""The {name} property. datetime in UTC + All values will be converted to a datetime in UTC. + """ + docs + def p_get(self: Component) -> Optional[datetime]: + """Get the value.""" + if name not in self: + return None + dt = self.get(name) + if isinstance(dt, vText): + # we might be in an attribute that is not typed + value = vDDDTypes.from_ical(dt) + else: + value = getattr(dt, "dt", None) + if value is None or not isinstance(value, date): + raise InvalidCalendar(f"{name} must be a datetime in UTC, not {value}") + return tzp.localize_utc(value) + + def p_set(self: Component, value: datetime): + """Set the value""" + if not isinstance(value, date): + raise TypeError(f"{name} takes a datetime in UTC, not {value}") + self.pop(name) + self.add(name, tzp.localize_utc(value)) + + + return property(p_get, p_set, doc=docs) class Component(CaselessDict): """Component is the base object for calendar, Event and the other @@ -494,11 +535,51 @@ def __eq__(self, other): return True + DTSTAMP = create_utc_property("DTSTAMP", """RFC 5545: + + Conformance: This property MUST be included in the "VEVENT", + "VTODO", "VJOURNAL", or "VFREEBUSY" calendar components. + + Description: In the case of an iCalendar object that specifies a + "METHOD" property, this property specifies the date and time that + the instance of the iCalendar object was created. In the case of + an iCalendar object that doesn't specify a "METHOD" property, this + property specifies the date and time that the information + associated with the calendar component was last revised in the + calendar store. + + The value MUST be specified in the UTC time format. + + In the case of an iCalendar object that doesn't specify a "METHOD" + property, this property is equivalent to the "LAST-MODIFIED" + property. + """) + LAST_MODIFIED = create_utc_property("LAST-MODIFIED", """RFC 5545: + + Purpose: This property specifies the date and time that the + information associated with the calendar component was last + revised in the calendar store. + + Note: This is analogous to the modification date and time for a + file in the file system. + + Conformance: This property can be specified in the "VEVENT", + "VTODO", "VJOURNAL", or "VTIMEZONE" calendar components. + """) + + def is_thunderbird(self) -> bool: + """Whether this component has attributes that indicate that Mozilla Thunderbird created it.""" + return any(attr.startswith("X-MOZ-") for attr in self.keys()) + + + ####################################### # components defined in RFC 5545 def create_single_property(prop:str, value_attr:str, value_type:tuple[type], type_def:type, doc:str): - """Create a single property getter and setter.""" + """Create a single property getter and setter. + + This is a getter and setter for a property that only occurs once or not (None).""" def p_get(self : Component): default = object() @@ -540,13 +621,14 @@ def p_del(self:Component): return property(p_get, p_set, p_del, p_doc) -def is_date(dt: date) -> bool: - """Whether this is a date and not a datetime.""" - return isinstance(dt, date) and not isinstance(dt, datetime) - -def is_datetime(dt: date) -> bool: - """Whether this is a date and not a datetime.""" - return isinstance(dt, datetime) +_X_MOZ_SNOOZE_TIME = create_utc_property( + "X-MOZ-SNOOZE-TIME", + "Thunderbird: Alarms before this time are snoozed." +) +_X_MOZ_LASTACK = create_utc_property( + "X-MOZ-LASTACK", + "Thunderbird: Alarms before this time are acknowledged." +) def _get_duration(self: Component) -> Optional[timedelta]: """Getter for property DURATION.""" @@ -619,6 +701,26 @@ class Event(Component): 'RSTATUS', 'RELATED', 'RESOURCES', 'RDATE', 'RRULE' ) ignore_exceptions = True + + @property + def alarms(self) -> Alarms: + """Compute the alarm times for this component. + + >>> from icalendar import Event + >>> event = Event.example("rfc_9074_example_1") + >>> len(event.alarms.times) + 1 + >>> alarm_time = event.alarms.times[0] + >>> alarm_time.trigger # The time when the alarm pops up + datetime.datetime(2021, 3, 2, 10, 15, tzinfo=ZoneInfo(key='America/New_York')) + >>> alarm_time.is_active() # This alarm has not been acknowledged + True + + Note that this only uses DTSTART and DTEND, but ignores + RDATE, EXDATE, and RRULE properties. + """ + from icalendar.alarms import Alarms + return Alarms(self) @classmethod def example(cls, name:str) -> Event: @@ -710,6 +812,9 @@ def end(self, end: date | datetime | None): """Set the end.""" self.DTEND = end + X_MOZ_SNOOZE_TIME = _X_MOZ_SNOOZE_TIME + X_MOZ_LASTACK = _X_MOZ_LASTACK + class Todo(Component): """ @@ -818,6 +923,26 @@ def duration(self) -> timedelta: """ return self.end - self.start + X_MOZ_SNOOZE_TIME = _X_MOZ_SNOOZE_TIME + X_MOZ_LASTACK = _X_MOZ_LASTACK + + @property + def alarms(self) -> Alarms: + """Compute the alarm times for this component. + + >>> from datetime import datetime + >>> from icalendar import Todo + >>> todo = Todo() # empty without alarms + >>> todo.start = datetime(2024, 10, 26, 10, 21) + >>> len(todo.alarms.times) + 0 + + Note that this only uses DTSTART and DUE, but ignores + RDATE, EXDATE, and RRULE properties. + """ + from icalendar.alarms import Alarms + return Alarms(self) + class Journal(Component): """A descriptive text at a certain time or associated with a component. @@ -1103,6 +1228,168 @@ class Alarm(Component): multiple = ('ATTENDEE', 'ATTACH', 'RELATED-TO') + @property + def REPEAT(self) -> int: + """The REPEAT property of an alarm component. + + The alarm can be defined such that it triggers repeatedly. A + definition of an alarm with a repeating trigger MUST include both + the "DURATION" and "REPEAT" properties. The "DURATION" property + specifies the delay period, after which the alarm will repeat. + The "REPEAT" property specifies the number of additional + repetitions that the alarm will be triggered. This repetition + count is in addition to the initial triggering of the alarm. + """ + try: + return int(self.get("REPEAT", 0)) + except ValueError as e: + raise InvalidCalendar("REPEAT must be an int") from e + + @REPEAT.setter + def REPEAT(self, value: int) -> None: + """The REPEAT property of an alarm component.""" + self["REPEAT"] = int(value) + + DURATION = property(_get_duration, _set_duration, _del_duration, + """The DURATION property of an alarm component. + + The alarm can be defined such that it triggers repeatedly. A + definition of an alarm with a repeating trigger MUST include both + the "DURATION" and "REPEAT" properties. The "DURATION" property + specifies the delay period, after which the alarm will repeat. + """) + + ACKNOWLEDGED = create_utc_property("ACKNOWLEDGED", + """This is defined in RFC 9074: + + Purpose: This property specifies the UTC date and time at which the + corresponding alarm was last sent or acknowledged. + + This property is used to specify when an alarm was last sent or acknowledged. + This allows clients to determine when a pending alarm has been acknowledged + by a calendar user so that any alerts can be dismissed across multiple devices. + It also allows clients to track repeating alarms or alarms on recurring events or + to-dos to ensure that the right number of missed alarms can be tracked. + + Clients SHOULD set this property to the current date-time value in UTC + when a calendar user acknowledges a pending alarm. Certain kinds of alarms, + such as email-based alerts, might not provide feedback as to when the calendar user + sees them. For those kinds of alarms, the client SHOULD set this property + when the alarm is triggered and the action is successfully carried out. + + When an alarm is triggered on a client, clients can check to see if an "ACKNOWLEDGED" + property is present. If it is, and the value of that property is greater than or + equal to the computed trigger time for the alarm, then the client SHOULD NOT trigger + the alarm. Similarly, if an alarm has been triggered and + an "alert" has been presented to a calendar user, clients can monitor + the iCalendar data to determine whether an "ACKNOWLEDGED" property is added or + changed in the alarm component. If the value of any "ACKNOWLEDGED" property + in the alarm changes and is greater than or equal to the trigger time of the alarm, + then clients SHOULD dismiss or cancel any "alert" presented to the calendar user. + """) + + TRIGGER = create_single_property( + "TRIGGER", "dt", (datetime, timedelta), Optional[Union[timedelta, datetime]], + """Purpose: This property specifies when an alarm will trigger. + + Value Type: The default value type is DURATION. The value type can + be set to a DATE-TIME value type, in which case the value MUST + specify a UTC-formatted DATE-TIME value. + + Either a positive or negative duration may be specified for the + "TRIGGER" property. An alarm with a positive duration is + triggered after the associated start or end of the event or to-do. + An alarm with a negative duration is triggered before the + associated start or end of the event or to-do.""" + ) + + @property + def TRIGGER_RELATED(self) -> str: + """The RELATED parameter of the TRIGGER property. + + Values are either "START" (default) or "END". + + A value of START will set the alarm to trigger off the + start of the associated event or to-do. A value of END will set + the alarm to trigger off the end of the associated event or to-do. + + In this example, we create an alarm that triggers two hours after the + end of its parent component: + + >>> from icalendar import Alarm + >>> from datetime import timedelta + >>> alarm = Alarm() + >>> alarm.TRIGGER = timedelta(hours=2) + >>> alarm.TRIGGER_RELATED = "END" + """ + trigger = self.get("TRIGGER") + if trigger is None: + return "START" + return trigger.params.get("RELATED", "START") + + @TRIGGER_RELATED.setter + def TRIGGER_RELATED(self, value: str): + """Set "START" or "END".""" + trigger = self.get("TRIGGER") + if trigger is None: + raise ValueError("You must set a TRIGGER before setting the RELATED parameter.") + trigger.params["RELATED"] = value + + class Triggers(NamedTuple): + """The computed times of alarm triggers. + + start - triggers relative to the start of the Event or Todo (timedelta) + + end - triggers relative to the end of the Event or Todo (timedelta) + + absolute - triggers at a datetime in UTC + """ + start: tuple[timedelta] + end: tuple[timedelta] + absolute: tuple[datetime] + + @property + def triggers(self): + """The computed triggers of an Alarm. + + This takes the TRIGGER, DURATION and REPEAT properties into account. + + Here, we create an alarm that triggers 3 times before the start of the + parent component: + + >>> from icalendar import Alarm + >>> from datetime import timedelta + >>> alarm = Alarm() + >>> alarm.TRIGGER = timedelta(hours=-4) # trigger 4 hours before START + >>> alarm.DURATION = timedelta(hours=1) # after 1 hour trigger again + >>> alarm.REPEAT = 2 # trigger 2 more times + >>> alarm.triggers.start == (timedelta(hours=-4), timedelta(hours=-3), timedelta(hours=-2)) + True + >>> alarm.triggers.end + () + >>> alarm.triggers.absolute + () + """ + start = [] + end = [] + absolute = [] + trigger = self.TRIGGER + if trigger is not None: + if isinstance(trigger, date): + absolute.append(trigger) + add = absolute + elif self.TRIGGER_RELATED == "START": + start.append(trigger) + add = start + else: + end.append(trigger) + add = end + duration = self.DURATION + if duration is not None: + for _ in range(self.REPEAT): + add.append(add[-1] + duration) + return self.Triggers(start=tuple(start), end=tuple(end), absolute=tuple(absolute)) + class Calendar(Component): """ The "VCALENDAR" object is a collection of calendar information. diff --git a/src/icalendar/prop.py b/src/icalendar/prop.py index c2969ecc..2e5ac643 100644 --- a/src/icalendar/prop.py +++ b/src/icalendar/prop.py @@ -35,28 +35,25 @@ These types are mainly used for parsing and file generation. But you can set them directly. """ -from datetime import date -from datetime import datetime -from datetime import time -from datetime import timedelta -from datetime import tzinfo -from icalendar.caselessdict import CaselessDict -from icalendar.parser import Parameters -from icalendar.parser import escape_char -from icalendar.parser import unescape_char -from icalendar.parser_tools import ( - DEFAULT_ENCODING, SEQUENCE_TYPES, to_unicode, from_unicode, ICAL_TYPE -) - import base64 import binascii -from .timezone import tzp import re import time as _time - -from typing import Optional, Union +from datetime import date, datetime, time, timedelta, tzinfo from enum import Enum, auto +from typing import Optional, Union + +from icalendar.caselessdict import CaselessDict +from icalendar.parser import Parameters, escape_char, unescape_char +from icalendar.parser_tools import ( + DEFAULT_ENCODING, + ICAL_TYPE, + SEQUENCE_TYPES, + from_unicode, + to_unicode, +) +from . import timezone as _timezone DURATION_REGEX = re.compile(r'([-+]?)P(?:(\d+)W)?(?:(\d+)D)?' r'(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$') @@ -408,9 +405,28 @@ def to_ical(self): @staticmethod def from_ical(ical, timezone=None): + """Create a datetime from the RFC string. + + Format: YYYYMMDDTHHMMSS + + >>> from icalendar import vDatetime + >>> vDatetime.from_ical("20210302T101500") + datetime.datetime(2021, 3, 2, 10, 15) + + >>> vDatetime.from_ical("20210302T101500", "America/New_York") + datetime.datetime(2021, 3, 2, 10, 15, tzinfo=ZoneInfo(key='America/New_York')) + + >>> from zoneinfo import ZoneInfo + >>> timezone = ZoneInfo("Europe/Berlin") + >>> vDatetime.from_ical("20210302T101500", timezone) + datetime.datetime(2021, 3, 2, 10, 15, tzinfo=ZoneInfo(key='Europe/Berlin')) + + """ tzinfo = None - if timezone: - tzinfo = tzp.timezone(timezone) + if isinstance(timezone, str): + tzinfo = _timezone.tzp.timezone(timezone) + elif timezone is not None: + tzinfo = timezone try: timetuple = ( @@ -422,15 +438,15 @@ def from_ical(ical, timezone=None): int(ical[13:15]), # second ) if tzinfo: - return tzp.localize(datetime(*timetuple), tzinfo) + return _timezone.tzp.localize(datetime(*timetuple), tzinfo) elif not ical[15:]: return datetime(*timetuple) elif ical[15:16] == 'Z': - return tzp.localize_utc(datetime(*timetuple)) + return _timezone.tzp.localize_utc(datetime(*timetuple)) else: raise ValueError(ical) - except Exception: - raise ValueError(f'Wrong datetime format: {ical}') + except Exception as e: + raise ValueError(f'Wrong datetime format: {ical}') from e class vDuration(TimeBase): diff --git a/src/icalendar/tests/alarms/rfc_5545_absolute_alarm_example.ics b/src/icalendar/tests/alarms/rfc_5545_absolute_alarm_example.ics new file mode 100644 index 00000000..9f7f71f3 --- /dev/null +++ b/src/icalendar/tests/alarms/rfc_5545_absolute_alarm_example.ics @@ -0,0 +1,7 @@ +BEGIN:VALARM +TRIGGER;VALUE=DATE-TIME:19970317T133000Z +REPEAT:4 +DURATION:PT15M +ACTION:AUDIO +ATTACH;FMTTYPE=audio/basic:ftp://example.com/pub/sounds/bell-01.aud +END:VALARM diff --git a/src/icalendar/tests/alarms/rfc_5545_end.ics b/src/icalendar/tests/alarms/rfc_5545_end.ics new file mode 100644 index 00000000..a9f52ddd --- /dev/null +++ b/src/icalendar/tests/alarms/rfc_5545_end.ics @@ -0,0 +1,8 @@ +BEGIN:VALARM +TRIGGER;RELATED=END:-P2D +ACTION:EMAIL +ATTENDEE:mailto:john_doe@example.com +SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING *** +DESCRIPTION:A draft agenda needs to be sent out to the attendees to the weekly managers meeting (MGR-LIST). Attached is a pointer the document template for the agenda file. +ATTACH;FMTTYPE=application/msword:http://example.com/templates/agenda.doc +END:VALARM diff --git a/src/icalendar/tests/alarms/start_date.ics b/src/icalendar/tests/alarms/start_date.ics new file mode 100644 index 00000000..cc87c948 --- /dev/null +++ b/src/icalendar/tests/alarms/start_date.ics @@ -0,0 +1,8 @@ +BEGIN:VALARM +TRIGGER;RELATED=START:-P2D +ACTION:EMAIL +ATTENDEE:mailto:john_doe@example.com +SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING *** +DESCRIPTION:A draft agenda needs to be sent out to the attendees to the weekly managers meeting (MGR-LIST). Attached is a pointer the document template for the agenda file. +ATTACH;FMTTYPE=application/msword:http://example.com/templates/agenda.doc +END:VALARM diff --git a/src/icalendar/tests/calendars/alarm_etar_future.ics b/src/icalendar/tests/calendars/alarm_etar_future.ics new file mode 100644 index 00000000..d2735f5d --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_etar_future.ics @@ -0,0 +1,235 @@ +BEGIN:VCALENDAR +PRODID:-//Offline Calendar//iCal Import/Export 2.8.1//EN +VERSION:2.0 +METHOD:PUBLISH +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Europe/London +TZURL:http://tzurl.org/zoneinfo/Europe/London +X-LIC-LOCATION:Europe/London +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19961027T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +BEGIN:STANDARD +TZOFFSETFROM:-000115 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:18471201T000115 +RDATE:18471201T000115 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19160521T020000 +RDATE:19160521T020000 +RDATE:19170408T020000 +RDATE:19180324T020000 +RDATE:19190330T020000 +RDATE:19200328T020000 +RDATE:19210403T020000 +RDATE:19220326T020000 +RDATE:19230422T020000 +RDATE:19240413T020000 +RDATE:19250419T020000 +RDATE:19260418T020000 +RDATE:19270410T020000 +RDATE:19280422T020000 +RDATE:19290421T020000 +RDATE:19300413T020000 +RDATE:19310419T020000 +RDATE:19320417T020000 +RDATE:19330409T020000 +RDATE:19340422T020000 +RDATE:19350414T020000 +RDATE:19360419T020000 +RDATE:19370418T020000 +RDATE:19380410T020000 +RDATE:19390416T020000 +RDATE:19400225T020000 +RDATE:19460414T020000 +RDATE:19470316T020000 +RDATE:19480314T020000 +RDATE:19490403T020000 +RDATE:19500416T020000 +RDATE:19510415T020000 +RDATE:19520420T020000 +RDATE:19530419T020000 +RDATE:19540411T020000 +RDATE:19550417T020000 +RDATE:19560422T020000 +RDATE:19570414T020000 +RDATE:19580420T020000 +RDATE:19590419T020000 +RDATE:19600410T020000 +RDATE:19610326T020000 +RDATE:19620325T020000 +RDATE:19630331T020000 +RDATE:19640322T020000 +RDATE:19650321T020000 +RDATE:19660320T020000 +RDATE:19670319T020000 +RDATE:19680218T020000 +RDATE:19720319T020000 +RDATE:19730318T020000 +RDATE:19740317T020000 +RDATE:19750316T020000 +RDATE:19760321T020000 +RDATE:19770320T020000 +RDATE:19780319T020000 +RDATE:19790318T020000 +RDATE:19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19161001T030000 +RDATE:19161001T030000 +RDATE:19170917T030000 +RDATE:19180930T030000 +RDATE:19190929T030000 +RDATE:19201025T030000 +RDATE:19211003T030000 +RDATE:19221008T030000 +RDATE:19230916T030000 +RDATE:19240921T030000 +RDATE:19251004T030000 +RDATE:19261003T030000 +RDATE:19271002T030000 +RDATE:19281007T030000 +RDATE:19291006T030000 +RDATE:19301005T030000 +RDATE:19311004T030000 +RDATE:19321002T030000 +RDATE:19331008T030000 +RDATE:19341007T030000 +RDATE:19351006T030000 +RDATE:19361004T030000 +RDATE:19371003T030000 +RDATE:19381002T030000 +RDATE:19391119T030000 +RDATE:19451007T030000 +RDATE:19461006T030000 +RDATE:19471102T030000 +RDATE:19481031T030000 +RDATE:19491030T030000 +RDATE:19501022T030000 +RDATE:19511021T030000 +RDATE:19521026T030000 +RDATE:19531004T030000 +RDATE:19541003T030000 +RDATE:19551002T030000 +RDATE:19561007T030000 +RDATE:19571006T030000 +RDATE:19581005T030000 +RDATE:19591004T030000 +RDATE:19601002T030000 +RDATE:19611029T030000 +RDATE:19621028T030000 +RDATE:19631027T030000 +RDATE:19641025T030000 +RDATE:19651024T030000 +RDATE:19661023T030000 +RDATE:19671029T030000 +RDATE:19711031T030000 +RDATE:19721029T030000 +RDATE:19731028T030000 +RDATE:19741027T030000 +RDATE:19751026T030000 +RDATE:19761024T030000 +RDATE:19771023T030000 +RDATE:19781029T030000 +RDATE:19791028T030000 +RDATE:19801026T030000 +RDATE:19811025T020000 +RDATE:19821024T020000 +RDATE:19831023T020000 +RDATE:19841028T020000 +RDATE:19851027T020000 +RDATE:19861026T020000 +RDATE:19871025T020000 +RDATE:19881023T020000 +RDATE:19891029T020000 +RDATE:19901028T020000 +RDATE:19911027T020000 +RDATE:19921025T020000 +RDATE:19931024T020000 +RDATE:19941023T020000 +RDATE:19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +TZNAME:BDST +DTSTART:19410504T010000 +RDATE:19410504T010000 +RDATE:19420405T010000 +RDATE:19430404T010000 +RDATE:19440402T010000 +RDATE:19450402T010000 +RDATE:19470413T010000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19410810T030000 +RDATE:19410810T030000 +RDATE:19420809T030000 +RDATE:19430815T030000 +RDATE:19440917T030000 +RDATE:19450715T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19681026T230000 +RDATE:19681026T230000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETFROM:+0000 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19960101T000000 +RDATE:19960101T000000 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +DTSTAMP:20241005T112701Z +UID:17281276213728ad54d03afa44d1ca60b8c52afaece9e@sufficientlysecure.org +SUMMARY:event with alarms android +STATUS:CONFIRMED +DTSTART;TZID=Europe/London:20241005T130000 +DTEND:20241005T130000Z +LAST-MODIFIED:20241005T112701Z +BEGIN:VALARM +TRIGGER:-PT30M +ACTION:DISPLAY +DESCRIPTION:event with alarms android +END:VALARM +BEGIN:VALARM +TRIGGER:-PT25M +ACTION:DISPLAY +DESCRIPTION:event with alarms android +END:VALARM +BEGIN:VALARM +TRIGGER:-PT5M +ACTION:DISPLAY +DESCRIPTION:event with alarms android +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_etar_notification.ics b/src/icalendar/tests/calendars/alarm_etar_notification.ics new file mode 100644 index 00000000..bbee664b --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_etar_notification.ics @@ -0,0 +1,235 @@ +BEGIN:VCALENDAR +PRODID:-//Offline Calendar//iCal Import/Export 2.8.1//EN +VERSION:2.0 +METHOD:PUBLISH +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Europe/London +TZURL:http://tzurl.org/zoneinfo/Europe/London +X-LIC-LOCATION:Europe/London +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19961027T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +BEGIN:STANDARD +TZOFFSETFROM:-000115 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:18471201T000115 +RDATE:18471201T000115 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19160521T020000 +RDATE:19160521T020000 +RDATE:19170408T020000 +RDATE:19180324T020000 +RDATE:19190330T020000 +RDATE:19200328T020000 +RDATE:19210403T020000 +RDATE:19220326T020000 +RDATE:19230422T020000 +RDATE:19240413T020000 +RDATE:19250419T020000 +RDATE:19260418T020000 +RDATE:19270410T020000 +RDATE:19280422T020000 +RDATE:19290421T020000 +RDATE:19300413T020000 +RDATE:19310419T020000 +RDATE:19320417T020000 +RDATE:19330409T020000 +RDATE:19340422T020000 +RDATE:19350414T020000 +RDATE:19360419T020000 +RDATE:19370418T020000 +RDATE:19380410T020000 +RDATE:19390416T020000 +RDATE:19400225T020000 +RDATE:19460414T020000 +RDATE:19470316T020000 +RDATE:19480314T020000 +RDATE:19490403T020000 +RDATE:19500416T020000 +RDATE:19510415T020000 +RDATE:19520420T020000 +RDATE:19530419T020000 +RDATE:19540411T020000 +RDATE:19550417T020000 +RDATE:19560422T020000 +RDATE:19570414T020000 +RDATE:19580420T020000 +RDATE:19590419T020000 +RDATE:19600410T020000 +RDATE:19610326T020000 +RDATE:19620325T020000 +RDATE:19630331T020000 +RDATE:19640322T020000 +RDATE:19650321T020000 +RDATE:19660320T020000 +RDATE:19670319T020000 +RDATE:19680218T020000 +RDATE:19720319T020000 +RDATE:19730318T020000 +RDATE:19740317T020000 +RDATE:19750316T020000 +RDATE:19760321T020000 +RDATE:19770320T020000 +RDATE:19780319T020000 +RDATE:19790318T020000 +RDATE:19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19161001T030000 +RDATE:19161001T030000 +RDATE:19170917T030000 +RDATE:19180930T030000 +RDATE:19190929T030000 +RDATE:19201025T030000 +RDATE:19211003T030000 +RDATE:19221008T030000 +RDATE:19230916T030000 +RDATE:19240921T030000 +RDATE:19251004T030000 +RDATE:19261003T030000 +RDATE:19271002T030000 +RDATE:19281007T030000 +RDATE:19291006T030000 +RDATE:19301005T030000 +RDATE:19311004T030000 +RDATE:19321002T030000 +RDATE:19331008T030000 +RDATE:19341007T030000 +RDATE:19351006T030000 +RDATE:19361004T030000 +RDATE:19371003T030000 +RDATE:19381002T030000 +RDATE:19391119T030000 +RDATE:19451007T030000 +RDATE:19461006T030000 +RDATE:19471102T030000 +RDATE:19481031T030000 +RDATE:19491030T030000 +RDATE:19501022T030000 +RDATE:19511021T030000 +RDATE:19521026T030000 +RDATE:19531004T030000 +RDATE:19541003T030000 +RDATE:19551002T030000 +RDATE:19561007T030000 +RDATE:19571006T030000 +RDATE:19581005T030000 +RDATE:19591004T030000 +RDATE:19601002T030000 +RDATE:19611029T030000 +RDATE:19621028T030000 +RDATE:19631027T030000 +RDATE:19641025T030000 +RDATE:19651024T030000 +RDATE:19661023T030000 +RDATE:19671029T030000 +RDATE:19711031T030000 +RDATE:19721029T030000 +RDATE:19731028T030000 +RDATE:19741027T030000 +RDATE:19751026T030000 +RDATE:19761024T030000 +RDATE:19771023T030000 +RDATE:19781029T030000 +RDATE:19791028T030000 +RDATE:19801026T030000 +RDATE:19811025T020000 +RDATE:19821024T020000 +RDATE:19831023T020000 +RDATE:19841028T020000 +RDATE:19851027T020000 +RDATE:19861026T020000 +RDATE:19871025T020000 +RDATE:19881023T020000 +RDATE:19891029T020000 +RDATE:19901028T020000 +RDATE:19911027T020000 +RDATE:19921025T020000 +RDATE:19931024T020000 +RDATE:19941023T020000 +RDATE:19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +TZNAME:BDST +DTSTART:19410504T010000 +RDATE:19410504T010000 +RDATE:19420405T010000 +RDATE:19430404T010000 +RDATE:19440402T010000 +RDATE:19450402T010000 +RDATE:19470413T010000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19410810T030000 +RDATE:19410810T030000 +RDATE:19420809T030000 +RDATE:19430815T030000 +RDATE:19440917T030000 +RDATE:19450715T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19681026T230000 +RDATE:19681026T230000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETFROM:+0000 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19960101T000000 +RDATE:19960101T000000 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +DTSTAMP:20241005T113036Z +UID:17281276213728ad54d03afa44d1ca60b8c52afaece9e@sufficientlysecure.org +SUMMARY:event with alarms android +STATUS:CONFIRMED +DTSTART;TZID=Europe/London:20241005T130000 +DTEND:20241005T130000Z +LAST-MODIFIED:20241005T112701Z +BEGIN:VALARM +TRIGGER:-PT30M +ACTION:DISPLAY +DESCRIPTION:event with alarms android +END:VALARM +BEGIN:VALARM +TRIGGER:-PT25M +ACTION:DISPLAY +DESCRIPTION:event with alarms android +END:VALARM +BEGIN:VALARM +TRIGGER:-PT5M +ACTION:DISPLAY +DESCRIPTION:event with alarms android +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_etar_notification_clicked.ics b/src/icalendar/tests/calendars/alarm_etar_notification_clicked.ics new file mode 100644 index 00000000..c61e048f --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_etar_notification_clicked.ics @@ -0,0 +1,225 @@ +BEGIN:VCALENDAR +PRODID:-//Offline Calendar//iCal Import/Export 2.8.1//EN +VERSION:2.0 +METHOD:PUBLISH +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:Europe/London +TZURL:http://tzurl.org/zoneinfo/Europe/London +X-LIC-LOCATION:Europe/London +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19961027T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +BEGIN:STANDARD +TZOFFSETFROM:-000115 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:18471201T000115 +RDATE:18471201T000115 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19160521T020000 +RDATE:19160521T020000 +RDATE:19170408T020000 +RDATE:19180324T020000 +RDATE:19190330T020000 +RDATE:19200328T020000 +RDATE:19210403T020000 +RDATE:19220326T020000 +RDATE:19230422T020000 +RDATE:19240413T020000 +RDATE:19250419T020000 +RDATE:19260418T020000 +RDATE:19270410T020000 +RDATE:19280422T020000 +RDATE:19290421T020000 +RDATE:19300413T020000 +RDATE:19310419T020000 +RDATE:19320417T020000 +RDATE:19330409T020000 +RDATE:19340422T020000 +RDATE:19350414T020000 +RDATE:19360419T020000 +RDATE:19370418T020000 +RDATE:19380410T020000 +RDATE:19390416T020000 +RDATE:19400225T020000 +RDATE:19460414T020000 +RDATE:19470316T020000 +RDATE:19480314T020000 +RDATE:19490403T020000 +RDATE:19500416T020000 +RDATE:19510415T020000 +RDATE:19520420T020000 +RDATE:19530419T020000 +RDATE:19540411T020000 +RDATE:19550417T020000 +RDATE:19560422T020000 +RDATE:19570414T020000 +RDATE:19580420T020000 +RDATE:19590419T020000 +RDATE:19600410T020000 +RDATE:19610326T020000 +RDATE:19620325T020000 +RDATE:19630331T020000 +RDATE:19640322T020000 +RDATE:19650321T020000 +RDATE:19660320T020000 +RDATE:19670319T020000 +RDATE:19680218T020000 +RDATE:19720319T020000 +RDATE:19730318T020000 +RDATE:19740317T020000 +RDATE:19750316T020000 +RDATE:19760321T020000 +RDATE:19770320T020000 +RDATE:19780319T020000 +RDATE:19790318T020000 +RDATE:19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19161001T030000 +RDATE:19161001T030000 +RDATE:19170917T030000 +RDATE:19180930T030000 +RDATE:19190929T030000 +RDATE:19201025T030000 +RDATE:19211003T030000 +RDATE:19221008T030000 +RDATE:19230916T030000 +RDATE:19240921T030000 +RDATE:19251004T030000 +RDATE:19261003T030000 +RDATE:19271002T030000 +RDATE:19281007T030000 +RDATE:19291006T030000 +RDATE:19301005T030000 +RDATE:19311004T030000 +RDATE:19321002T030000 +RDATE:19331008T030000 +RDATE:19341007T030000 +RDATE:19351006T030000 +RDATE:19361004T030000 +RDATE:19371003T030000 +RDATE:19381002T030000 +RDATE:19391119T030000 +RDATE:19451007T030000 +RDATE:19461006T030000 +RDATE:19471102T030000 +RDATE:19481031T030000 +RDATE:19491030T030000 +RDATE:19501022T030000 +RDATE:19511021T030000 +RDATE:19521026T030000 +RDATE:19531004T030000 +RDATE:19541003T030000 +RDATE:19551002T030000 +RDATE:19561007T030000 +RDATE:19571006T030000 +RDATE:19581005T030000 +RDATE:19591004T030000 +RDATE:19601002T030000 +RDATE:19611029T030000 +RDATE:19621028T030000 +RDATE:19631027T030000 +RDATE:19641025T030000 +RDATE:19651024T030000 +RDATE:19661023T030000 +RDATE:19671029T030000 +RDATE:19711031T030000 +RDATE:19721029T030000 +RDATE:19731028T030000 +RDATE:19741027T030000 +RDATE:19751026T030000 +RDATE:19761024T030000 +RDATE:19771023T030000 +RDATE:19781029T030000 +RDATE:19791028T030000 +RDATE:19801026T030000 +RDATE:19811025T020000 +RDATE:19821024T020000 +RDATE:19831023T020000 +RDATE:19841028T020000 +RDATE:19851027T020000 +RDATE:19861026T020000 +RDATE:19871025T020000 +RDATE:19881023T020000 +RDATE:19891029T020000 +RDATE:19901028T020000 +RDATE:19911027T020000 +RDATE:19921025T020000 +RDATE:19931024T020000 +RDATE:19941023T020000 +RDATE:19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +TZNAME:BDST +DTSTART:19410504T010000 +RDATE:19410504T010000 +RDATE:19420405T010000 +RDATE:19430404T010000 +RDATE:19440402T010000 +RDATE:19450402T010000 +RDATE:19470413T010000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19410810T030000 +RDATE:19410810T030000 +RDATE:19420809T030000 +RDATE:19430815T030000 +RDATE:19440917T030000 +RDATE:19450715T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +TZNAME:BST +DTSTART:19681026T230000 +RDATE:19681026T230000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETFROM:+0000 +TZOFFSETTO:+0000 +TZNAME:GMT +DTSTART:19960101T000000 +RDATE:19960101T000000 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +DTSTAMP:20241005T130738Z +UID:17281336589228ad54d03afa44d1ca60b8c52afaece9e@sufficientlysecure.org +SUMMARY:event with alarm acknowledged +STATUS:CONFIRMED +DTSTART;TZID=Europe/London:20241005T141700 +DTEND:20241005T141700Z +LAST-MODIFIED:20241005T130738Z +BEGIN:VALARM +TRIGGER:-PT10M +ACTION:DISPLAY +DESCRIPTION:event with alarm acknowledged +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_google_acknowledged.ics b/src/icalendar/tests/calendars/alarm_google_acknowledged.ics new file mode 100644 index 00000000..013c2405 --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_google_acknowledged.ics @@ -0,0 +1,60 @@ +BEGIN:VCALENDAR +PRODID:-//Google Inc//Google Calendar 70.9054//EN +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +X-WR-CALNAME:Nicco Kunzmann +X-WR-TIMEZONE:Europe/London +BEGIN:VTIMEZONE +TZID:Europe/Berlin +X-LIC-LOCATION:Europe/Berlin +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +TZNAME:GMT+2 +DTSTART:19700329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +TZNAME:GMT+1 +DTSTART:19701025T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +DTSTART:20241004T181500Z +DTEND:20241004T190000Z +DTSTAMP:20241004T180026Z +UID:79fs7pkqvht9m5igs0vjv1sfra@google.com +CREATED:20241004T175920Z +LAST-MODIFIED:20241004T175928Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:event with alarms +TRANSP:OPAQUE +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-P0DT0H10M0S +DESCRIPTION:This is an event reminder +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-P0DT0H14M0S +DESCRIPTION:This is an event reminder +END:VALARM +BEGIN:VALARM +ACTION:EMAIL +ATTENDEE:mailto:niccokunzmann@googlemail.com +TRIGGER:-P0DT0H15M0S +DESCRIPTION:This is an event reminder +SUMMARY:Alarm notification +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-P0DT0H15M0S +DESCRIPTION:This is an event reminder +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_google_future.ics b/src/icalendar/tests/calendars/alarm_google_future.ics new file mode 100644 index 00000000..f7e4e7ef --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_google_future.ics @@ -0,0 +1,60 @@ +BEGIN:VCALENDAR +PRODID:-//Google Inc//Google Calendar 70.9054//EN +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +X-WR-CALNAME:Nicco Kunzmann +X-WR-TIMEZONE:Europe/London +BEGIN:VTIMEZONE +TZID:Europe/Berlin +X-LIC-LOCATION:Europe/Berlin +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +TZNAME:GMT+2 +DTSTART:19700329T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +TZNAME:GMT+1 +DTSTART:19701025T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +DTSTART:20241004T181500Z +DTEND:20241004T190000Z +DTSTAMP:20241004T175945Z +UID:79fs7pkqvht9m5igs0vjv1sfra@google.com +CREATED:20241004T175920Z +LAST-MODIFIED:20241004T175928Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:event with alarms +TRANSP:OPAQUE +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-P0DT0H10M0S +DESCRIPTION:This is an event reminder +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-P0DT0H14M0S +DESCRIPTION:This is an event reminder +END:VALARM +BEGIN:VALARM +ACTION:EMAIL +ATTENDEE:mailto:niccokunzmann@googlemail.com +TRIGGER:-P0DT0H15M0S +DESCRIPTION:This is an event reminder +SUMMARY:Alarm notification +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-P0DT0H15M0S +DESCRIPTION:This is an event reminder +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_thunderbird_2_future.ics b/src/icalendar/tests/calendars/alarm_thunderbird_2_future.ics new file mode 100644 index 00000000..6d25d536 --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_thunderbird_2_future.ics @@ -0,0 +1,624 @@ +BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/London +X-TZINFO:Europe/London[2024a] +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:-000115 +TZNAME:Europe/London(STD) +DTSTART:18471201T000000 +RDATE:18471201T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19160521T020000 +RDATE:19160521T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19161001T030000 +RDATE:19161001T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19170408T020000 +RDATE:19170408T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19170917T030000 +RDATE:19170917T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19180324T020000 +RDATE:19180324T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19180930T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1MO;UNTIL=19190929T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19190330T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19200328T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19201025T030000 +RDATE:19201025T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19210403T020000 +RDATE:19210403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19211003T030000 +RDATE:19211003T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19220326T020000 +RDATE:19220326T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19221008T030000 +RDATE:19221008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19230422T020000 +RDATE:19230422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19240413T020000 +RDATE:19240413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19230916T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3SU;UNTIL=19240921T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19250419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19260418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19270410T020000 +RDATE:19270410T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19280422T020000 +RDATE:19280422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19290421T020000 +RDATE:19290421T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19300413T020000 +RDATE:19300413T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19310419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19320417T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19251004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19321002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19330409T020000 +RDATE:19330409T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19331008T030000 +RDATE:19331008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19340422T020000 +RDATE:19340422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19350414T020000 +RDATE:19350414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19360419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19370418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19380410T020000 +RDATE:19380410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19341007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19381002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19390416T020000 +RDATE:19390416T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19400225T020000 +RDATE:19400225T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19410504T020000 +RDATE:19410504T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19410810T030000 +RDATE:19410810T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19420405T020000 +RDATE:19420405T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19420809T030000 +RDATE:19420809T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19430404T020000 +RDATE:19430404T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19430815T030000 +RDATE:19430815T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19440402T020000 +RDATE:19440402T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19440917T030000 +RDATE:19440917T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19450402T020000 +RDATE:19450402T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19391119T030000 +RDATE:19391119T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19450715T030000 +RDATE:19450715T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19460414T020000 +RDATE:19460414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19470316T020000 +RDATE:19470316T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19470413T020000 +RDATE:19470413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19451007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19461006T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19470810T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19471102T030000 +RDATE:19471102T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19480314T020000 +RDATE:19480314T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19490403T020000 +RDATE:19490403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19481031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19491030T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19501022T030000 +RDATE:19501022T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19511021T030000 +RDATE:19511021T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19521026T030000 +RDATE:19521026T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19500416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19530419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19540411T020000 +RDATE:19540411T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19550417T020000 +RDATE:19550417T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19560422T020000 +RDATE:19560422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19570414T020000 +RDATE:19570414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19580420T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19590419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19600410T020000 +RDATE:19600410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19531004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19601002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19610326T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19630331T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19640322T020000 +RDATE:19640322T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19611029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19641025T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19651024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19661023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19650321T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19670319T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19671029T030000 +RDATE:19671029T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+010000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19681027T000000 +RDATE:19681027T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19680218T020000 +RDATE:19680218T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19711031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19751026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19761024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19771023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19720319T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19781029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19801026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19811025T020000 +RDATE:19811025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19821024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19831023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19841028T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19871025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19881023T020000 +RDATE:19881023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19891029T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19921025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19931024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T010000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19961027T020000 +RDATE:19961027T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:(DST) +DTSTART:19970330T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:(STD) +DTSTART:19971026T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20241023T173412Z +LAST-MODIFIED:20241023T173453Z +DTSTAMP:20241023T173453Z +UID:731b9b91-cf72-499b-bbc9-c53c28e21fc7 +SUMMARY:event +DTSTART;TZID=Europe/London:20241023T190000 +DTEND;TZID=Europe/London:20241023T200000 +TRANSP:OPAQUE +X-MOZ-GENERATION:2 +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT1M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT24M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed.ics b/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed.ics new file mode 100644 index 00000000..851a8db0 --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed.ics @@ -0,0 +1,626 @@ +BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/London +X-TZINFO:Europe/London[2024a] +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:-000115 +TZNAME:Europe/London(STD) +DTSTART:18471201T000000 +RDATE:18471201T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19160521T020000 +RDATE:19160521T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19161001T030000 +RDATE:19161001T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19170408T020000 +RDATE:19170408T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19170917T030000 +RDATE:19170917T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19180324T020000 +RDATE:19180324T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19180930T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1MO;UNTIL=19190929T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19190330T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19200328T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19201025T030000 +RDATE:19201025T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19210403T020000 +RDATE:19210403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19211003T030000 +RDATE:19211003T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19220326T020000 +RDATE:19220326T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19221008T030000 +RDATE:19221008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19230422T020000 +RDATE:19230422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19240413T020000 +RDATE:19240413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19230916T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3SU;UNTIL=19240921T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19250419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19260418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19270410T020000 +RDATE:19270410T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19280422T020000 +RDATE:19280422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19290421T020000 +RDATE:19290421T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19300413T020000 +RDATE:19300413T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19310419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19320417T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19251004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19321002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19330409T020000 +RDATE:19330409T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19331008T030000 +RDATE:19331008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19340422T020000 +RDATE:19340422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19350414T020000 +RDATE:19350414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19360419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19370418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19380410T020000 +RDATE:19380410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19341007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19381002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19390416T020000 +RDATE:19390416T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19400225T020000 +RDATE:19400225T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19410504T020000 +RDATE:19410504T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19410810T030000 +RDATE:19410810T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19420405T020000 +RDATE:19420405T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19420809T030000 +RDATE:19420809T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19430404T020000 +RDATE:19430404T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19430815T030000 +RDATE:19430815T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19440402T020000 +RDATE:19440402T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19440917T030000 +RDATE:19440917T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19450402T020000 +RDATE:19450402T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19391119T030000 +RDATE:19391119T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19450715T030000 +RDATE:19450715T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19460414T020000 +RDATE:19460414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19470316T020000 +RDATE:19470316T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19470413T020000 +RDATE:19470413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19451007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19461006T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19470810T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19471102T030000 +RDATE:19471102T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19480314T020000 +RDATE:19480314T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19490403T020000 +RDATE:19490403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19481031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19491030T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19501022T030000 +RDATE:19501022T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19511021T030000 +RDATE:19511021T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19521026T030000 +RDATE:19521026T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19500416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19530419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19540411T020000 +RDATE:19540411T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19550417T020000 +RDATE:19550417T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19560422T020000 +RDATE:19560422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19570414T020000 +RDATE:19570414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19580420T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19590419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19600410T020000 +RDATE:19600410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19531004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19601002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19610326T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19630331T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19640322T020000 +RDATE:19640322T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19611029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19641025T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19651024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19661023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19650321T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19670319T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19671029T030000 +RDATE:19671029T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+010000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19681027T000000 +RDATE:19681027T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19680218T020000 +RDATE:19680218T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19711031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19751026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19761024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19771023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19720319T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19781029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19801026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19811025T020000 +RDATE:19811025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19821024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19831023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19841028T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19871025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19881023T020000 +RDATE:19881023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19891029T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19921025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19931024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T010000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19961027T020000 +RDATE:19961027T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:(DST) +DTSTART:19970330T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:(STD) +DTSTART:19971026T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20241023T173412Z +LAST-MODIFIED:20241023T173630Z +DTSTAMP:20241023T173630Z +UID:731b9b91-cf72-499b-bbc9-c53c28e21fc7 +SUMMARY:event +X-MOZ-LASTACK:20241023T173630Z +DTSTART;TZID=Europe/London:20241023T190000 +DTEND;TZID=Europe/London:20241023T200000 +TRANSP:OPAQUE +X-MOZ-GENERATION:3 +X-MOZ-SNOOZE-TIME:20241023T174130Z +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT1M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT24M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed_and_closed.ics b/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed_and_closed.ics new file mode 100644 index 00000000..cfa7035b --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed_and_closed.ics @@ -0,0 +1,625 @@ +BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/London +X-TZINFO:Europe/London[2024a] +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:-000115 +TZNAME:Europe/London(STD) +DTSTART:18471201T000000 +RDATE:18471201T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19160521T020000 +RDATE:19160521T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19161001T030000 +RDATE:19161001T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19170408T020000 +RDATE:19170408T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19170917T030000 +RDATE:19170917T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19180324T020000 +RDATE:19180324T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19180930T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1MO;UNTIL=19190929T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19190330T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19200328T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19201025T030000 +RDATE:19201025T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19210403T020000 +RDATE:19210403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19211003T030000 +RDATE:19211003T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19220326T020000 +RDATE:19220326T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19221008T030000 +RDATE:19221008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19230422T020000 +RDATE:19230422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19240413T020000 +RDATE:19240413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19230916T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3SU;UNTIL=19240921T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19250419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19260418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19270410T020000 +RDATE:19270410T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19280422T020000 +RDATE:19280422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19290421T020000 +RDATE:19290421T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19300413T020000 +RDATE:19300413T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19310419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19320417T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19251004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19321002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19330409T020000 +RDATE:19330409T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19331008T030000 +RDATE:19331008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19340422T020000 +RDATE:19340422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19350414T020000 +RDATE:19350414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19360419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19370418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19380410T020000 +RDATE:19380410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19341007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19381002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19390416T020000 +RDATE:19390416T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19400225T020000 +RDATE:19400225T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19410504T020000 +RDATE:19410504T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19410810T030000 +RDATE:19410810T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19420405T020000 +RDATE:19420405T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19420809T030000 +RDATE:19420809T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19430404T020000 +RDATE:19430404T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19430815T030000 +RDATE:19430815T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19440402T020000 +RDATE:19440402T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19440917T030000 +RDATE:19440917T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19450402T020000 +RDATE:19450402T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19391119T030000 +RDATE:19391119T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19450715T030000 +RDATE:19450715T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19460414T020000 +RDATE:19460414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19470316T020000 +RDATE:19470316T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19470413T020000 +RDATE:19470413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19451007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19461006T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19470810T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19471102T030000 +RDATE:19471102T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19480314T020000 +RDATE:19480314T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19490403T020000 +RDATE:19490403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19481031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19491030T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19501022T030000 +RDATE:19501022T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19511021T030000 +RDATE:19511021T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19521026T030000 +RDATE:19521026T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19500416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19530419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19540411T020000 +RDATE:19540411T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19550417T020000 +RDATE:19550417T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19560422T020000 +RDATE:19560422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19570414T020000 +RDATE:19570414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19580420T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19590419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19600410T020000 +RDATE:19600410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19531004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19601002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19610326T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19630331T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19640322T020000 +RDATE:19640322T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19611029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19641025T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19651024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19661023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19650321T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19670319T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19671029T030000 +RDATE:19671029T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+010000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19681027T000000 +RDATE:19681027T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19680218T020000 +RDATE:19680218T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19711031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19751026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19761024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19771023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19720319T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19781029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19801026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19811025T020000 +RDATE:19811025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19821024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19831023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19841028T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19871025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19881023T020000 +RDATE:19881023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19891029T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19921025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19931024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T010000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19961027T020000 +RDATE:19961027T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:(DST) +DTSTART:19970330T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:(STD) +DTSTART:19971026T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20241023T173412Z +LAST-MODIFIED:20241023T174207Z +DTSTAMP:20241023T174207Z +UID:731b9b91-cf72-499b-bbc9-c53c28e21fc7 +SUMMARY:event +X-MOZ-LASTACK:20241023T174207Z +DTSTART;TZID=Europe/London:20241023T190000 +DTEND;TZID=Europe/London:20241023T200000 +TRANSP:OPAQUE +X-MOZ-GENERATION:4 +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT1M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT24M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed_and_popped_up.ics b/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed_and_popped_up.ics new file mode 100644 index 00000000..851a8db0 --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_5_min_postponed_and_popped_up.ics @@ -0,0 +1,626 @@ +BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/London +X-TZINFO:Europe/London[2024a] +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:-000115 +TZNAME:Europe/London(STD) +DTSTART:18471201T000000 +RDATE:18471201T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19160521T020000 +RDATE:19160521T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19161001T030000 +RDATE:19161001T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19170408T020000 +RDATE:19170408T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19170917T030000 +RDATE:19170917T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19180324T020000 +RDATE:19180324T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19180930T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1MO;UNTIL=19190929T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19190330T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19200328T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19201025T030000 +RDATE:19201025T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19210403T020000 +RDATE:19210403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19211003T030000 +RDATE:19211003T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19220326T020000 +RDATE:19220326T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19221008T030000 +RDATE:19221008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19230422T020000 +RDATE:19230422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19240413T020000 +RDATE:19240413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19230916T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3SU;UNTIL=19240921T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19250419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19260418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19270410T020000 +RDATE:19270410T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19280422T020000 +RDATE:19280422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19290421T020000 +RDATE:19290421T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19300413T020000 +RDATE:19300413T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19310419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19320417T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19251004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19321002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19330409T020000 +RDATE:19330409T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19331008T030000 +RDATE:19331008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19340422T020000 +RDATE:19340422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19350414T020000 +RDATE:19350414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19360419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19370418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19380410T020000 +RDATE:19380410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19341007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19381002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19390416T020000 +RDATE:19390416T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19400225T020000 +RDATE:19400225T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19410504T020000 +RDATE:19410504T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19410810T030000 +RDATE:19410810T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19420405T020000 +RDATE:19420405T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19420809T030000 +RDATE:19420809T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19430404T020000 +RDATE:19430404T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19430815T030000 +RDATE:19430815T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19440402T020000 +RDATE:19440402T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19440917T030000 +RDATE:19440917T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19450402T020000 +RDATE:19450402T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19391119T030000 +RDATE:19391119T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19450715T030000 +RDATE:19450715T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19460414T020000 +RDATE:19460414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19470316T020000 +RDATE:19470316T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19470413T020000 +RDATE:19470413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19451007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19461006T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19470810T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19471102T030000 +RDATE:19471102T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19480314T020000 +RDATE:19480314T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19490403T020000 +RDATE:19490403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19481031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19491030T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19501022T030000 +RDATE:19501022T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19511021T030000 +RDATE:19511021T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19521026T030000 +RDATE:19521026T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19500416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19530419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19540411T020000 +RDATE:19540411T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19550417T020000 +RDATE:19550417T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19560422T020000 +RDATE:19560422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19570414T020000 +RDATE:19570414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19580420T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19590419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19600410T020000 +RDATE:19600410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19531004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19601002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19610326T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19630331T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19640322T020000 +RDATE:19640322T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19611029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19641025T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19651024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19661023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19650321T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19670319T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19671029T030000 +RDATE:19671029T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+010000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19681027T000000 +RDATE:19681027T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19680218T020000 +RDATE:19680218T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19711031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19751026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19761024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19771023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19720319T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19781029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19801026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19811025T020000 +RDATE:19811025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19821024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19831023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19841028T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19871025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19881023T020000 +RDATE:19881023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19891029T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19921025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19931024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T010000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19961027T020000 +RDATE:19961027T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:(DST) +DTSTART:19970330T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:(STD) +DTSTART:19971026T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20241023T173412Z +LAST-MODIFIED:20241023T173630Z +DTSTAMP:20241023T173630Z +UID:731b9b91-cf72-499b-bbc9-c53c28e21fc7 +SUMMARY:event +X-MOZ-LASTACK:20241023T173630Z +DTSTART;TZID=Europe/London:20241023T190000 +DTEND;TZID=Europe/London:20241023T200000 +TRANSP:OPAQUE +X-MOZ-GENERATION:3 +X-MOZ-SNOOZE-TIME:20241023T174130Z +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT1M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT24M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_popped_up.ics b/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_popped_up.ics new file mode 100644 index 00000000..6d25d536 --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_thunderbird_2_notification_popped_up.ics @@ -0,0 +1,624 @@ +BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/London +X-TZINFO:Europe/London[2024a] +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:-000115 +TZNAME:Europe/London(STD) +DTSTART:18471201T000000 +RDATE:18471201T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19160521T020000 +RDATE:19160521T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19161001T030000 +RDATE:19161001T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19170408T020000 +RDATE:19170408T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19170917T030000 +RDATE:19170917T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19180324T020000 +RDATE:19180324T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19180930T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1MO;UNTIL=19190929T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19190330T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19200328T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19201025T030000 +RDATE:19201025T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19210403T020000 +RDATE:19210403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19211003T030000 +RDATE:19211003T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19220326T020000 +RDATE:19220326T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19221008T030000 +RDATE:19221008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19230422T020000 +RDATE:19230422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19240413T020000 +RDATE:19240413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19230916T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3SU;UNTIL=19240921T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19250419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19260418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19270410T020000 +RDATE:19270410T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19280422T020000 +RDATE:19280422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19290421T020000 +RDATE:19290421T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19300413T020000 +RDATE:19300413T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19310419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19320417T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19251004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19321002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19330409T020000 +RDATE:19330409T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19331008T030000 +RDATE:19331008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19340422T020000 +RDATE:19340422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19350414T020000 +RDATE:19350414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19360419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19370418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19380410T020000 +RDATE:19380410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19341007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19381002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19390416T020000 +RDATE:19390416T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19400225T020000 +RDATE:19400225T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19410504T020000 +RDATE:19410504T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19410810T030000 +RDATE:19410810T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19420405T020000 +RDATE:19420405T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19420809T030000 +RDATE:19420809T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19430404T020000 +RDATE:19430404T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19430815T030000 +RDATE:19430815T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19440402T020000 +RDATE:19440402T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19440917T030000 +RDATE:19440917T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19450402T020000 +RDATE:19450402T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19391119T030000 +RDATE:19391119T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19450715T030000 +RDATE:19450715T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19460414T020000 +RDATE:19460414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19470316T020000 +RDATE:19470316T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19470413T020000 +RDATE:19470413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19451007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19461006T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19470810T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19471102T030000 +RDATE:19471102T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19480314T020000 +RDATE:19480314T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19490403T020000 +RDATE:19490403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19481031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19491030T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19501022T030000 +RDATE:19501022T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19511021T030000 +RDATE:19511021T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19521026T030000 +RDATE:19521026T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19500416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19530419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19540411T020000 +RDATE:19540411T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19550417T020000 +RDATE:19550417T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19560422T020000 +RDATE:19560422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19570414T020000 +RDATE:19570414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19580420T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19590419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19600410T020000 +RDATE:19600410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19531004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19601002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19610326T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19630331T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19640322T020000 +RDATE:19640322T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19611029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19641025T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19651024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19661023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19650321T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19670319T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19671029T030000 +RDATE:19671029T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+010000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19681027T000000 +RDATE:19681027T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19680218T020000 +RDATE:19680218T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19711031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19751026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19761024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19771023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19720319T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19781029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19801026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19811025T020000 +RDATE:19811025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19821024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19831023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19841028T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19871025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19881023T020000 +RDATE:19881023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19891029T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19921025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19931024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T010000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19961027T020000 +RDATE:19961027T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:(DST) +DTSTART:19970330T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:(STD) +DTSTART:19971026T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20241023T173412Z +LAST-MODIFIED:20241023T173453Z +DTSTAMP:20241023T173453Z +UID:731b9b91-cf72-499b-bbc9-c53c28e21fc7 +SUMMARY:event +DTSTART;TZID=Europe/London:20241023T190000 +DTEND;TZID=Europe/London:20241023T200000 +TRANSP:OPAQUE +X-MOZ-GENERATION:2 +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT1M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT24M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_thunderbird_closed.ics b/src/icalendar/tests/calendars/alarm_thunderbird_closed.ics new file mode 100644 index 00000000..524f069a --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_thunderbird_closed.ics @@ -0,0 +1,625 @@ +BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/London +X-TZINFO:Europe/London[2024a] +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:-000115 +TZNAME:Europe/London(STD) +DTSTART:18471201T000000 +RDATE:18471201T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19160521T020000 +RDATE:19160521T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19161001T030000 +RDATE:19161001T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19170408T020000 +RDATE:19170408T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19170917T030000 +RDATE:19170917T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19180324T020000 +RDATE:19180324T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19180930T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1MO;UNTIL=19190929T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19190330T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19200328T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19201025T030000 +RDATE:19201025T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19210403T020000 +RDATE:19210403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19211003T030000 +RDATE:19211003T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19220326T020000 +RDATE:19220326T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19221008T030000 +RDATE:19221008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19230422T020000 +RDATE:19230422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19240413T020000 +RDATE:19240413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19230916T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3SU;UNTIL=19240921T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19250419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19260418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19270410T020000 +RDATE:19270410T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19280422T020000 +RDATE:19280422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19290421T020000 +RDATE:19290421T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19300413T020000 +RDATE:19300413T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19310419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19320417T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19251004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19321002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19330409T020000 +RDATE:19330409T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19331008T030000 +RDATE:19331008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19340422T020000 +RDATE:19340422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19350414T020000 +RDATE:19350414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19360419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19370418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19380410T020000 +RDATE:19380410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19341007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19381002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19390416T020000 +RDATE:19390416T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19400225T020000 +RDATE:19400225T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19410504T020000 +RDATE:19410504T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19410810T030000 +RDATE:19410810T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19420405T020000 +RDATE:19420405T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19420809T030000 +RDATE:19420809T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19430404T020000 +RDATE:19430404T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19430815T030000 +RDATE:19430815T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19440402T020000 +RDATE:19440402T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19440917T030000 +RDATE:19440917T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19450402T020000 +RDATE:19450402T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19391119T030000 +RDATE:19391119T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19450715T030000 +RDATE:19450715T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19460414T020000 +RDATE:19460414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19470316T020000 +RDATE:19470316T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19470413T020000 +RDATE:19470413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19451007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19461006T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19470810T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19471102T030000 +RDATE:19471102T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19480314T020000 +RDATE:19480314T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19490403T020000 +RDATE:19490403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19481031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19491030T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19501022T030000 +RDATE:19501022T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19511021T030000 +RDATE:19511021T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19521026T030000 +RDATE:19521026T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19500416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19530419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19540411T020000 +RDATE:19540411T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19550417T020000 +RDATE:19550417T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19560422T020000 +RDATE:19560422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19570414T020000 +RDATE:19570414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19580420T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19590419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19600410T020000 +RDATE:19600410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19531004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19601002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19610326T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19630331T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19640322T020000 +RDATE:19640322T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19611029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19641025T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19651024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19661023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19650321T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19670319T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19671029T030000 +RDATE:19671029T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+010000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19681027T000000 +RDATE:19681027T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19680218T020000 +RDATE:19680218T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19711031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19751026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19761024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19771023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19720319T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19781029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19801026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19811025T020000 +RDATE:19811025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19821024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19831023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19841028T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19871025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19881023T020000 +RDATE:19881023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19891029T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19921025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19931024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T010000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19961027T020000 +RDATE:19961027T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:(DST) +DTSTART:19970330T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:(STD) +DTSTART:19971026T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20241023T131035Z +LAST-MODIFIED:20241023T141941Z +DTSTAMP:20241023T141941Z +UID:b9a23b47-f109-4e7a-908c-75e925b27def +SUMMARY:event with alarms +X-MOZ-LASTACK:20241023T141941Z +DTSTART;TZID=Europe/London:20241023T150000 +DTEND;TZID=Europe/London:20241023T160000 +TRANSP:OPAQUE +X-MOZ-GENERATION:6 +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT15M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT45M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_thunderbird_future.ics b/src/icalendar/tests/calendars/alarm_thunderbird_future.ics new file mode 100644 index 00000000..5c491a6f --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_thunderbird_future.ics @@ -0,0 +1,624 @@ +BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/London +X-TZINFO:Europe/London[2024a] +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:-000115 +TZNAME:Europe/London(STD) +DTSTART:18471201T000000 +RDATE:18471201T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19160521T020000 +RDATE:19160521T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19161001T030000 +RDATE:19161001T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19170408T020000 +RDATE:19170408T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19170917T030000 +RDATE:19170917T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19180324T020000 +RDATE:19180324T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19180930T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1MO;UNTIL=19190929T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19190330T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19200328T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19201025T030000 +RDATE:19201025T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19210403T020000 +RDATE:19210403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19211003T030000 +RDATE:19211003T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19220326T020000 +RDATE:19220326T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19221008T030000 +RDATE:19221008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19230422T020000 +RDATE:19230422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19240413T020000 +RDATE:19240413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19230916T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3SU;UNTIL=19240921T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19250419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19260418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19270410T020000 +RDATE:19270410T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19280422T020000 +RDATE:19280422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19290421T020000 +RDATE:19290421T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19300413T020000 +RDATE:19300413T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19310419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19320417T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19251004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19321002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19330409T020000 +RDATE:19330409T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19331008T030000 +RDATE:19331008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19340422T020000 +RDATE:19340422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19350414T020000 +RDATE:19350414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19360419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19370418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19380410T020000 +RDATE:19380410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19341007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19381002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19390416T020000 +RDATE:19390416T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19400225T020000 +RDATE:19400225T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19410504T020000 +RDATE:19410504T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19410810T030000 +RDATE:19410810T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19420405T020000 +RDATE:19420405T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19420809T030000 +RDATE:19420809T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19430404T020000 +RDATE:19430404T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19430815T030000 +RDATE:19430815T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19440402T020000 +RDATE:19440402T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19440917T030000 +RDATE:19440917T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19450402T020000 +RDATE:19450402T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19391119T030000 +RDATE:19391119T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19450715T030000 +RDATE:19450715T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19460414T020000 +RDATE:19460414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19470316T020000 +RDATE:19470316T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19470413T020000 +RDATE:19470413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19451007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19461006T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19470810T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19471102T030000 +RDATE:19471102T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19480314T020000 +RDATE:19480314T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19490403T020000 +RDATE:19490403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19481031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19491030T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19501022T030000 +RDATE:19501022T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19511021T030000 +RDATE:19511021T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19521026T030000 +RDATE:19521026T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19500416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19530419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19540411T020000 +RDATE:19540411T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19550417T020000 +RDATE:19550417T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19560422T020000 +RDATE:19560422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19570414T020000 +RDATE:19570414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19580420T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19590419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19600410T020000 +RDATE:19600410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19531004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19601002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19610326T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19630331T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19640322T020000 +RDATE:19640322T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19611029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19641025T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19651024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19661023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19650321T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19670319T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19671029T030000 +RDATE:19671029T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+010000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19681027T000000 +RDATE:19681027T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19680218T020000 +RDATE:19680218T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19711031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19751026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19761024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19771023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19720319T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19781029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19801026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19811025T020000 +RDATE:19811025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19821024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19831023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19841028T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19871025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19881023T020000 +RDATE:19881023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19891029T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19921025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19931024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T010000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19961027T020000 +RDATE:19961027T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:(DST) +DTSTART:19970330T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:(STD) +DTSTART:19971026T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20241023T131035Z +LAST-MODIFIED:20241023T131141Z +DTSTAMP:20241023T131141Z +UID:b9a23b47-f109-4e7a-908c-75e925b27def +SUMMARY:event with alarms +DTSTART;TZID=Europe/London:20241023T150000 +DTEND;TZID=Europe/London:20241023T160000 +TRANSP:OPAQUE +X-MOZ-GENERATION:2 +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT15M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT45M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/calendars/alarm_thunderbird_snoozed_until_1457.ics b/src/icalendar/tests/calendars/alarm_thunderbird_snoozed_until_1457.ics new file mode 100644 index 00000000..89aa1f32 --- /dev/null +++ b/src/icalendar/tests/calendars/alarm_thunderbird_snoozed_until_1457.ics @@ -0,0 +1,626 @@ +BEGIN:VCALENDAR +PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN +VERSION:2.0 +BEGIN:VTIMEZONE +TZID:Europe/London +X-TZINFO:Europe/London[2024a] +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:-000115 +TZNAME:Europe/London(STD) +DTSTART:18471201T000000 +RDATE:18471201T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19160521T020000 +RDATE:19160521T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19161001T030000 +RDATE:19161001T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19170408T020000 +RDATE:19170408T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19170917T030000 +RDATE:19170917T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19180324T020000 +RDATE:19180324T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19180930T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=-1MO;UNTIL=19190929T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19190330T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19200328T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19201025T030000 +RDATE:19201025T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19210403T020000 +RDATE:19210403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19211003T030000 +RDATE:19211003T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19220326T020000 +RDATE:19220326T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19221008T030000 +RDATE:19221008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19230422T020000 +RDATE:19230422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19240413T020000 +RDATE:19240413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19230916T030000 +RRULE:FREQ=YEARLY;BYMONTH=9;BYDAY=3SU;UNTIL=19240921T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19250419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19260418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19270410T020000 +RDATE:19270410T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19280422T020000 +RDATE:19280422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19290421T020000 +RDATE:19290421T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19300413T020000 +RDATE:19300413T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19310419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19320417T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19251004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19321002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19330409T020000 +RDATE:19330409T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19331008T030000 +RDATE:19331008T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19340422T020000 +RDATE:19340422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19350414T020000 +RDATE:19350414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19360419T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19370418T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19380410T020000 +RDATE:19380410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19341007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19381002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19390416T020000 +RDATE:19390416T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19400225T020000 +RDATE:19400225T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19410504T020000 +RDATE:19410504T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19410810T030000 +RDATE:19410810T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19420405T020000 +RDATE:19420405T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19420809T030000 +RDATE:19420809T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19430404T020000 +RDATE:19430404T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19430815T030000 +RDATE:19430815T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19440402T020000 +RDATE:19440402T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19440917T030000 +RDATE:19440917T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19450402T020000 +RDATE:19450402T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19391119T030000 +RDATE:19391119T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19450715T030000 +RDATE:19450715T030000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19460414T020000 +RDATE:19460414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19470316T020000 +RDATE:19470316T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+020000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(DST) +DTSTART:19470413T020000 +RDATE:19470413T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19451007T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19461006T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+020000 +TZNAME:Europe/London(DST) +DTSTART:19470810T030000 +RDATE:19470810T030000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19471102T030000 +RDATE:19471102T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19480314T020000 +RDATE:19480314T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19490403T020000 +RDATE:19490403T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19481031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19491030T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19501022T030000 +RDATE:19501022T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19511021T030000 +RDATE:19511021T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19521026T030000 +RDATE:19521026T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19500416T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19530419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19540411T020000 +RDATE:19540411T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19550417T020000 +RDATE:19550417T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19560422T020000 +RDATE:19560422T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19570414T020000 +RDATE:19570414T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19580420T020000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=3SU;UNTIL=19590419T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19600410T020000 +RDATE:19600410T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19531004T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19601002T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19610326T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19630331T020000 +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19640322T020000 +RDATE:19640322T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19611029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19641025T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19651024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19661023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19650321T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19670319T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19671029T030000 +RDATE:19671029T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+010000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19681027T000000 +RDATE:19681027T000000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19680218T020000 +RDATE:19680218T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19711031T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19751026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19761024T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19771023T030000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19720319T020000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=3SU;UNTIL=19800316T020000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19781029T030000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19801026T030000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19811025T020000 +RDATE:19811025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19821024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19831023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19841028T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19871025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19881023T020000 +RDATE:19881023T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19891029T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=19921025T020000 +END:STANDARD +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19931024T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=4SU;UNTIL=19951022T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:Europe/London(DST) +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU;UNTIL=19960331T010000 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:Europe/London(STD) +DTSTART:19961027T020000 +RDATE:19961027T020000 +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETTO:+010000 +TZOFFSETFROM:+000000 +TZNAME:(DST) +DTSTART:19970330T010000 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETTO:+000000 +TZOFFSETFROM:+010000 +TZNAME:(STD) +DTSTART:19971026T020000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CREATED:20241023T131035Z +LAST-MODIFIED:20241023T135202Z +DTSTAMP:20241023T135202Z +UID:b9a23b47-f109-4e7a-908c-75e925b27def +SUMMARY:event with alarms +X-MOZ-LASTACK:20241023T135202Z +DTSTART;TZID=Europe/London:20241023T150000 +DTEND;TZID=Europe/London:20241023T160000 +TRANSP:OPAQUE +X-MOZ-GENERATION:4 +X-MOZ-SNOOZE-TIME:20241023T135702Z +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT15M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +BEGIN:VALARM +ACTION:DISPLAY +TRIGGER:-PT45M +DESCRIPTION:Mozilla Standardbeschreibung +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/src/icalendar/tests/conftest.py b/src/icalendar/tests/conftest.py index 8db1941e..3062b6d2 100644 --- a/src/icalendar/tests/conftest.py +++ b/src/icalendar/tests/conftest.py @@ -93,6 +93,7 @@ def multiple(self): CALENDARS_FOLDER = HERE / "calendars" TIMEZONES_FOLDER = HERE / "timezones" EVENTS_FOLDER = HERE / "events" +ALARMS_FOLDER = HERE / "alarms" @pytest.fixture(scope="module") @@ -110,6 +111,11 @@ def events(tzp): return DataSource(EVENTS_FOLDER, icalendar.Event.from_ical) +@pytest.fixture(scope="module") +def alarms(tzp): + return DataSource(ALARMS_FOLDER, icalendar.Alarm.from_ical) + + @pytest.fixture(params=PYTZ_UTC + [zoneinfo.ZoneInfo("UTC"), tz.UTC, tz.gettz("UTC")]) def utc(request, tzp): return request.param diff --git a/src/icalendar/tests/prop/test_alarm.py b/src/icalendar/tests/prop/test_alarm.py new file mode 100644 index 00000000..7decf33a --- /dev/null +++ b/src/icalendar/tests/prop/test_alarm.py @@ -0,0 +1,57 @@ +"""Test the properties of the alarm.""" + + +import pytest + +from icalendar.cal import Alarm, InvalidCalendar + + +def test_repeat_absent(): + """Test the absence of REPEAT.""" + assert Alarm().REPEAT == 0 + + +def test_repeat_number(): + """Test the absence of REPEAT.""" + assert Alarm({"REPEAT": 10}).REPEAT == 10 + + +def test_set_REPEAT(): + """Check setting the value.""" + a = Alarm() + a.REPEAT = 10 + assert a.REPEAT == 10 + + +def test_set_REPEAT_twice(): + """Check setting the value.""" + a = Alarm() + a.REPEAT = 10 + a.REPEAT = 20 + assert a.REPEAT == 20 + + +def test_add_REPEAT(): + """Check setting the value.""" + a = Alarm() + a.add("REPEAT", 10) + assert a.REPEAT == 10 + + +def test_invalid_repeat_value(): + """Check setting the value.""" + a = Alarm() + with pytest.raises(ValueError): + a.REPEAT = "asd" + a["REPEAT"] = "asd" + with pytest.raises(InvalidCalendar): + a.REPEAT # noqa: B018 + + +def test_alarm_to_string(): + a = Alarm() + a.REPEAT = 11 + assert a.to_ical() == b"BEGIN:VALARM\r\nREPEAT:11\r\nEND:VALARM\r\n" + + + diff --git a/src/icalendar/tests/prop/test_component.py b/src/icalendar/tests/prop/test_component.py new file mode 100644 index 00000000..adc5e21f --- /dev/null +++ b/src/icalendar/tests/prop/test_component.py @@ -0,0 +1,97 @@ +"""Test common properties of components.""" + +from datetime import date, datetime, timedelta + +import pytest + +from icalendar import Event, FreeBusy, Journal, Todo, vDDDTypes +from icalendar.cal import Component, InvalidCalendar + + +@pytest.fixture(params=[Event, Todo, Journal, FreeBusy]) +def dtstamp_comp(request): + """a component to test""" + return request.param() + + +def test_no_dtstamp(dtstamp_comp): + """We have None as a value.""" + assert dtstamp_comp.DTSTAMP is None + + +def set_dtstamp_attribute(component:Component, value:date): + """Use the setter.""" + component.DTSTAMP = value + +def set_dtstamp_item(component: Component, value:date): + """Use setitem.""" + component["DTSTAMP"] = vDDDTypes(value) + +def set_dtstamp_add(component: Component, value:date): + """Use add.""" + component.add("DTSTAMP", value) + + + +@pytest.mark.parametrize( + ("value", "timezone", "expected"), + [ + (datetime(2024, 10, 11, 23, 1), None, datetime(2024, 10, 11, 23, 1)), + (datetime(2024, 10, 11, 23, 1), "Europe/Berlin", datetime(2024, 10, 11, 21, 1)), + (datetime(2024, 10, 11, 22, 1), "UTC", datetime(2024, 10, 11, 22, 1)), + (date(2024, 10, 10), None, datetime(2024, 10, 10)), + ] +) +@pytest.mark.parametrize( + "set_dtstamp", [set_dtstamp_add, set_dtstamp_attribute, set_dtstamp_item] +) +def test_set_value_and_get_it(dtstamp_comp, value, timezone, expected, tzp, set_dtstamp): + """Set and get the DTSTAMP value.""" + dtstamp = value if timezone is None else tzp.localize(value, timezone) + set_dtstamp(dtstamp_comp, dtstamp) + in_utc = tzp.localize_utc(expected) + get_value = dtstamp_comp.get("DTSTAMP").dt + assert in_utc == get_value or set_dtstamp != set_dtstamp_attribute + assert in_utc == dtstamp_comp.DTSTAMP + + +@pytest.mark.parametrize( + "invalid_value", + [ + None, + timedelta() + ] +) +def test_set_invalid_value(invalid_value, dtstamp_comp): + """Check handling of invalid values.""" + with pytest.raises(TypeError) as e: + dtstamp_comp.DTSTAMP = invalid_value + assert e.value.args[0] == f"DTSTAMP takes a datetime in UTC, not {invalid_value}" + + +@pytest.mark.parametrize( + "invalid_value", + [ + None, + vDDDTypes(timedelta()) + ] +) +def test_get_invalid_value(invalid_value, dtstamp_comp): + """Check handling of invalid values.""" + dtstamp_comp["DTSTAMP"] = invalid_value + with pytest.raises(InvalidCalendar) as e: + dtstamp_comp.DTSTAMP # noqa: B018 + assert e.value.args[0] == f"DTSTAMP must be a datetime in UTC, not {getattr(invalid_value, 'dt', invalid_value)}" + + +def test_set_twice(dtstamp_comp, tzp): + """Set the value twice.""" + dtstamp_comp.DTSTAMP = date(2014, 1, 1) + dtstamp_comp.DTSTAMP = date(2014, 1, 2) + assert tzp.localize_utc(datetime(2014, 1, 2)) == dtstamp_comp.DTSTAMP + + +def test_last_modified(dtstamp_comp, tzp): + """Check we can set LAST_MODIFIED in the same way as DTSTAMP""" + dtstamp_comp.LAST_MODIFIED = date(2014, 1, 2) + assert tzp.localize_utc(datetime(2014, 1, 2)) == dtstamp_comp.LAST_MODIFIED diff --git a/src/icalendar/tests/test_issue_662_component_properties.py b/src/icalendar/tests/test_issue_662_component_properties.py index 095e94a6..b524c95a 100644 --- a/src/icalendar/tests/test_issue_662_component_properties.py +++ b/src/icalendar/tests/test_issue_662_component_properties.py @@ -4,6 +4,8 @@ import pytest +from icalendar.cal import Alarm + try: from zoneinfo import ZoneInfo except ImportError: @@ -16,6 +18,7 @@ Journal, Todo, vDDDTypes, + vDatetime, ) from icalendar.prop import vDuration @@ -493,3 +496,108 @@ def setting_twice_does_not_duplicate_the_entry(): assert j.start == date(2024, 1, 3) assert j.end == date(2024, 1, 3) + +@pytest.mark.parametrize( + ("file", "trigger", "related"), + [ + ("rfc_5545_absolute_alarm_example", vDatetime.from_ical("19970317T133000Z"), "START"), + ("rfc_5545_end", timedelta(days=-2), "END"), + ("start_date", timedelta(days=-2), "START"), + ] +) +def test_get_alarm_trigger_property(alarms, file, trigger, related): + """Get the trigger property.""" + alarm = alarms[file] + assert alarm.TRIGGER == trigger + assert alarm.TRIGGER_RELATED == related + + +def test_set_alarm_trigger(): + """Set the alarm trigger.""" + a = Alarm() + a.TRIGGER = timedelta(hours=1) + assert a.TRIGGER == timedelta(hours=1) + assert a.TRIGGER_RELATED == "START" + + +def test_set_alarm_trigger_related(): + """Set the alarm trigger.""" + a = Alarm() + a.TRIGGER = timedelta(hours=1) + a.TRIGGER_RELATED = "END" + assert a.TRIGGER == timedelta(hours=1) + assert a.TRIGGER_RELATED == "END" + + +def test_get_related_without_trigger(): + """The default is start""" + assert Alarm().TRIGGER_RELATED == "START" + +def test_cannot_set_related_without_trigger(): + """TRIGGER must be set to set the parameter.""" + with pytest.raises(ValueError) as e: + a = Alarm() + a.TRIGGER_RELATED = "END" + assert e.value.args[0] == "You must set a TRIGGER before setting the RELATED parameter." + + +@pytest.mark.parametrize( + ("file", "triggers"), + [ + ("rfc_5545_absolute_alarm_example", ((), (), (vDatetime.from_ical("19970317T133000Z"), vDatetime.from_ical("19970317T134500Z"),vDatetime.from_ical("19970317T140000Z"),vDatetime.from_ical("19970317T141500Z"),vDatetime.from_ical("19970317T143000Z"),))), + ("rfc_5545_end", ((), (timedelta(days=-2),), ())), + ("start_date", ((timedelta(days=-2),), (), ())), + ] +) +def test_get_alarm_triggers(alarms, file, triggers): + """Get the trigger property.""" + alarm = alarms[file] + print(tuple(alarm.triggers)) + print(triggers) + assert alarm.triggers == triggers + + +def test_triggers_emtpy_alarm(): + """An alarm with no trigger has no triggers.""" + assert Alarm().triggers == ((), (), ()) + +h1 = timedelta(hours=1) + +def test_triggers_emtpy_with_no_repeat(): + """Check incomplete values.""" + a = Alarm() + a.TRIGGER = h1 + a.DURATION = h1 + assert a.triggers == ((h1,), (), ()) + +def test_triggers_emtpy_with_no_duration(): + """Check incomplete values.""" + a = Alarm() + a.TRIGGER = h1 + a.REPEAT = 10 + assert a.triggers == ((h1,), (), ()) + + +@pytest.mark.parametrize( + ("file", "triggers"), + [ + ("rfc_5545_absolute_alarm_example", ((), (), (vDatetime.from_ical("19970317T133000Z"),))), + ("rfc_5545_end", ((), (timedelta(days=-2),), ())), + ("start_date", ((timedelta(days=-2),), (), ())), + ] +) +@pytest.mark.parametrize("duration", [timedelta(days=-1), h1]) +@pytest.mark.parametrize("repeat", [1, 3]) +def test_get_alarm_triggers_repeated(alarms, file, triggers, duration, repeat): + """Get the trigger property.""" + alarm = alarms[file].copy() + alarm.REPEAT = repeat + alarm.DURATION = duration + for expected, triggers in zip(triggers, alarm.triggers): + if not expected: + assert triggers == () + continue + assert len(triggers) == 1 + repeat + assert triggers[0] == expected[0] + for x, y in zip(triggers[:-1], triggers[1:]): + assert y - x == duration diff --git a/src/icalendar/tests/test_issue_716_alarm_extension.py b/src/icalendar/tests/test_issue_716_alarm_extension.py deleted file mode 100644 index b6beead9..00000000 --- a/src/icalendar/tests/test_issue_716_alarm_extension.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Test the alarm classification. - -Events can have alarms. -Alarms can be in this state: - -- active - the user wants the alarm to pop up -- acknowledged - the user no longer wants the alarm -- snoozed - the user moved that alarm to another time - -The alarms can only work on the properties of the event like -DTSTART, DTEND and DURATION. - -""" diff --git a/src/icalendar/tests/test_issue_716_alarm_time_computation.py b/src/icalendar/tests/test_issue_716_alarm_time_computation.py new file mode 100644 index 00000000..3f31368f --- /dev/null +++ b/src/icalendar/tests/test_issue_716_alarm_time_computation.py @@ -0,0 +1,347 @@ +"""Test the alarm time computation. + +Events can have alarms. +Alarms can be in this state: + +- active - the user wants the alarm to pop up +- acknowledged - the user no longer wants the alarm +- snoozed - the user moved that alarm to another time + +The alarms can only work on the properties of the event like +DTSTART, DTEND, and DURATION. + +""" + + +from datetime import date, datetime, timedelta, timezone + +import pytest + +from icalendar import Event +from icalendar.alarms import Alarms, IncompleteAlarmInformation +from icalendar.cal import Alarm +from icalendar.prop import vDatetime +from icalendar.tools import normalize_pytz + +UTC = timezone.utc +EXAMPLE_TRIGGER = datetime(1997, 3, 17, 13, 30, tzinfo=UTC) + + +def test_absolute_alarm_time_rfc_example(alarms): + """Check that the absolute alarm is recognized. + + The following example is for a "VALARM" calendar component + that specifies an audio alarm that will sound at a precise time + and repeat 4 more times at 15-minute intervals: + """ + a = Alarms(alarms.rfc_5545_absolute_alarm_example) + times = a.times + assert len(times) == 5 + for i, t in enumerate(times): + assert t.trigger == EXAMPLE_TRIGGER + timedelta(minutes=15 * i) + + +alarm_1 = Alarm() +alarm_1.add("TRIGGER", EXAMPLE_TRIGGER) +alarm_2 = Alarm() +alarm_2["TRIGGER"] = vDatetime(EXAMPLE_TRIGGER) + +@pytest.mark.parametrize( + "alarm", + [ + alarm_1, alarm_2 + ] +) +def test_absolute_alarm_time_with_vDatetime(alarm): + """Check that the absolute alarm is recognized. + + The following example is for a "VALARM" calendar component + that specifies an audio alarm that will sound at a precise time + and repeat 4 more times at 15-minute intervals: + """ + a = Alarms(alarm) + times = a.times + assert len(times) == 1 + assert times[0].trigger == EXAMPLE_TRIGGER + + +alarm_incomplete_1 = Alarm() +alarm_incomplete_1.TRIGGER = timedelta(hours=2) +alarm_incomplete_1.DURATION = timedelta(hours=1) +alarm_incomplete_2 = Alarm() +alarm_incomplete_2.TRIGGER = timedelta(hours=2) +alarm_incomplete_2.REPEAT = 100 + +@pytest.mark.parametrize("alarm", [alarm_incomplete_1, alarm_incomplete_2]) +def test_alarm_has_only_one_of_repeat_or_duration(alarm): + """This is an edge case and we should ignore the repetition.""" + a = Alarms(alarm) + a.set_start(datetime(2027, 12, 2)) + assert len(a.times) == 1 + + +@pytest.fixture(params=[(0, timedelta(minutes=-30)), (1, timedelta(minutes=-25))]) +def alarm_before_start(calendars, request): + """An example alarm relative to the start of a component.""" + index, td = request.param + alarm = calendars.alarm_etar_future.subcomponents[-1].subcomponents[index] + assert isinstance(alarm, Alarm) + assert alarm.get("TRIGGER").dt == td + alarm.test_td = td + return alarm + + +def test_cannot_compute_relative_alarm_without_start(alarm_before_start): + """We have an alarm without a start of a component.""" + with pytest.raises(IncompleteAlarmInformation) as e: + Alarms(alarm_before_start).times # noqa: B018 + assert e.value.args[0] == f"Use {Alarms.__name__}.{Alarms.set_start.__name__} because at least one alarm is relative to the start of a component." + + +@pytest.mark.parametrize( + ("dtstart", "timezone", "trigger"), + [ + (datetime(2024, 10, 29, 13, 10), "UTC", datetime(2024, 10, 29, 13, 10, tzinfo=UTC)), + (date(2024, 11, 16), None, datetime(2024, 11, 16, 0, 0)), + (datetime(2024, 10, 29, 13, 10), "Asia/Singapore", datetime(2024, 10, 29, 5, 10, tzinfo=UTC)), + (datetime(2024, 10, 29, 13, 20), None, datetime(2024, 10, 29, 13, 20)), + ] +) +def test_can_complete_relative_calculation_if_a_start_is_given(alarm_before_start, dtstart, timezone, trigger, tzp): + """The start is given and required.""" + start = (dtstart if timezone is None else tzp.localize(dtstart, timezone)) + alarms = Alarms(alarm_before_start) + alarms.set_start(start) + assert len(alarms.times) == 1 + time = alarms.times[0] + expected_trigger = normalize_pytz(trigger + alarm_before_start.test_td) + assert time.trigger == expected_trigger + + +@pytest.mark.parametrize("dtstart", [date(1998, 10, 1), date(2023, 12, 31)]) +def test_start_as_date_with_delta_as_date_stays_date(alarms, dtstart): + """If we have an alarm with a day delta and the event is a day event, we should stay as a date.""" + a = Alarms(alarms.start_date) + a.set_start(dtstart) + assert len(a.times) == 1 + assert a.times[0].trigger == dtstart - timedelta(days=2) + + +def test_cannot_compute_relative_alarm_without_end(alarms): + """We have an alarm without an end of a component.""" + with pytest.raises(IncompleteAlarmInformation) as e: + Alarms(alarms.rfc_5545_end).times # noqa: B018 + assert e.value.args[0] == f"Use {Alarms.__name__}.{Alarms.set_end.__name__} because at least one alarm is relative to the end of a component." + + +@pytest.mark.parametrize( + ("dtend", "timezone", "trigger"), + [ + (datetime(2024, 10, 29, 13, 10), "UTC", datetime(2024, 10, 29, 13, 10, tzinfo=UTC)), + (date(2024, 11, 16), None, date(2024, 11, 16)), + (datetime(2024, 10, 29, 13, 10), "Asia/Singapore", datetime(2024, 10, 29, 5, 10, tzinfo=UTC)), + (datetime(2024, 10, 29, 13, 20), None, datetime(2024, 10, 29, 13, 20)), + ] +) +def test_can_complete_relative_calculation(alarms, dtend, timezone, trigger, tzp): + """The start is given and required.""" + start = (dtend if timezone is None else tzp.localize(dtend, timezone)) + alarms = Alarms(alarms.rfc_5545_end) + alarms.set_end(start) + assert len(alarms.times) == 1 + time = alarms.times[0] + expected_trigger = normalize_pytz(trigger - timedelta(days=2)) + assert time.trigger == expected_trigger + + +@pytest.mark.parametrize("dtend", [date(1998, 10, 1), date(2023, 12, 31)]) +def test_end_as_date_with_delta_as_date_stays_date(alarms, dtend): + """If we have an alarm with a day delta and the event is a day event, we should stay as a date.""" + a = Alarms(alarms.rfc_5545_end) + a.set_end(dtend) + assert len(a.times) == 1 + assert a.times[0].trigger == dtend - timedelta(days=2) + + + +def test_add_multiple_alarms(alarms): + """We can add multiple alarms.""" + a = Alarms() + a.add_alarm(alarms.start_date) + a.add_alarm(alarms.rfc_5545_end) + a.add_alarm(alarms.rfc_5545_absolute_alarm_example) + with pytest.raises(IncompleteAlarmInformation): + a.times # noqa: B018 + a.set_start(datetime(2012, 3, 5)) + with pytest.raises(IncompleteAlarmInformation): + a.times # noqa: B018 + a.set_end(datetime(2012, 3, 5)) + assert len(a.times) == 7 + + +def test_alarms_from_event_have_right_times(calendars): + """We can collect from an event.""" + event = calendars.alarm_etar_future.subcomponents[-1] + a = Alarms(event) + assert len(a.times) == 3 + assert a.times[0].parent == event + + +def test_cannot_set_the_event_twice(calendars): + """We cannot set an event twice. This make the state ambiguous.""" + event = calendars.alarm_etar_future.subcomponents[-1] + a = Alarms() + a.add_component(event) + a.add_component(event) # same component is ok + with pytest.raises(ValueError): + a.add_component(calendars.alarm_google_future.subcomponents[-1]) + + +@pytest.mark.parametrize( + ("calendar", "index", "count", "message"), + [ + ("alarm_etar_future", -1, 3, "Etar (1): we just created the alarm"), + ("alarm_etar_notification", -1, 2, "Etar (2): the notification popped up"), + ("alarm_etar_notification_clicked", -1, 0, "Etar (3): the notification was dismissed"), # TODO: check that that is really true + ("alarm_google_future", -1, 4, "Google (1): we just created the event with alarms"), + ("alarm_google_acknowledged", -1, 2, "Google (2): 2 alarms happened at the same time"), + ("alarm_thunderbird_future", -1, 2, "Thunderbird (1.1): 2 alarms are set"), + ("alarm_thunderbird_snoozed_until_1457", -1, 2, "Thunderbird (1.2): 2 alarms are snoozed to another time"), + ("alarm_thunderbird_closed", -1, 0, "Thunderbird (1.3): all alarms are dismissed (closed)"), + ("alarm_thunderbird_2_future", -1, 2, "Thunderbird (2.1): 2 alarms active"), + ("alarm_thunderbird_2_notification_popped_up", -1, 2, "Thunderbird (2.2): one alarm popped up as a notification"), + ("alarm_thunderbird_2_notification_5_min_postponed", -1, 2, "Thunderbird (2.3): 1 alarm active and one postponed by 5 minutes"), + ("alarm_thunderbird_2_notification_5_min_postponed_and_popped_up", -1, 2, "Thunderbird (2.4): 1 alarm active and one postponed by 5 minutes and now popped up"), + ("alarm_thunderbird_2_notification_5_min_postponed_and_closed", -1, 1, "Thunderbird (2.5): 1 alarm active and one postponed by 5 minutes and is now acknowledged"), + ] +) +def test_number_of_active_alarms_from_calendar_software(calendars, calendar, index, count, message): + """Check that we extract calculate the correct amount of active alarms.""" + event = calendars[calendar].subcomponents[index] + a = Alarms(event) + active_alarms = a.active # We do not need to pass a timezone because the events have a timezone + assert len(active_alarms) == count, f"{message} - I expect {count} alarms active but got {len(active_alarms)}." + + +three_alarms = Alarm() +three_alarms.REPEAT = 2 +three_alarms.add("DURATION", timedelta(hours=1)) # 2 hours & 1 hour before +three_alarms.add("TRIGGER", -timedelta(hours=3)) # 3 hours before + + +@pytest.mark.parametrize( + ("start", "acknowledged", "timezone", "count"), + [ + (datetime(2024, 10, 10), datetime(2024, 10, 9), "UTC", 3), + (datetime(2024, 10, 10, 12), datetime(2024, 10, 10, 9, 1), "UTC", 2), + (datetime(2024, 10, 10, 12), datetime(2024, 10, 10, 10, 1), "UTC", 1), + (datetime(2024, 10, 10, 12), datetime(2024, 10, 10, 11, 1), "UTC", 0), + (datetime(2024, 10, 10, 12, tzinfo=timezone.utc), datetime(2024, 10, 10, 11, 1), None, 0), + ] +) +def test_number_of_active_alarms_with_moving_time(start, acknowledged, count, tzp, timezone): + """Check how many alarms are active after a time they are acknowledged.""" + a = Alarms() + a.add_alarm(three_alarms) + a.set_start(start) + a.set_local_timezone(timezone) + a.acknowledge_until(tzp.localize_utc(acknowledged)) + active = a.active + assert len(active) == count + + +def test_incomplete_alarm_information_for_active_state(tzp): + """Make sure we throw the right error.""" + a = Alarms() + a.add_alarm(three_alarms) + a.set_start(date(2017, 12, 1)) + a.acknowledge_until(tzp.localize_utc(datetime(2012, 10, 10, 12))) + with pytest.raises(IncompleteAlarmInformation) as e: + a.active # noqa: B018 + assert e.value.args[0] == f"A local timezone is required to check if the alarm is still active. Use Alarms.{Alarms.set_local_timezone.__name__}()." + + +@pytest.mark.parametrize( + "calendar_name", + [ + "alarm_etar_future", + "alarm_google_acknowledged", + "alarm_thunderbird_closed", + "alarm_thunderbird_future", + "alarm_thunderbird_snoozed_until_1457", + ] +) +def test_thunderbird_recognition(calendars, calendar_name): + """Check if we correctly discover Thunderbird's alarm algorithm.""" + calendar = calendars[calendar_name] + event = calendar.subcomponents[-1] + assert isinstance(event, Event) + assert event.is_thunderbird() == ("thunderbird" in calendar_name) + + +@pytest.mark.parametrize( + "snooze", + [ + datetime(2012, 10, 10, 11, 1), # before everything + datetime(2017, 12, 1, 10, 1), + datetime(2017, 12, 1, 11, 1), + datetime(2017, 12, 1, 12, 1), + datetime(2017, 12, 1, 13, 1), # snooze until after the start of the event + ] +) +def test_snoozed_alarm_has_trigger_at_snooze_time(tzp, snooze): + """When an alarm is snoozed, it pops up after the snooze time.""" + a = Alarms() + a.add_alarm(three_alarms) + a.set_start(datetime(2017, 12, 1, 13)) + a.set_local_timezone("UTC") + snooze_utc = tzp.localize_utc(snooze) + a.snooze_until(snooze_utc) + active = a.active + assert len(active) == 3 + for alarm in active: + assert alarm.trigger >= snooze_utc + + +@pytest.mark.parametrize( + ("event_index", "alarm_times"), + [ + # Assume that we have the following event with an alarm set to trigger 15 minutes before the meeting: + (1, ("20210302T101500",)), + # When the alarm is triggered, the user decides to "snooze" it for 5 minutes. + # The client acknowledges the original alarm and creates a new "snooze" + # alarm as a sibling of, and relates it to, the original alarm (note that + # both occurrences of "VALARM" reside within the same "parent" VEVENT): + (2, ("20210302T102000",)), + # When the "snooze" alarm is triggered, the user decides to "snooze" it + # again for an additional 5 minutes. The client once again acknowledges + # the original alarm, removes the triggered "snooze" alarm, and creates another + # new "snooze" alarm as a sibling of, and relates it to, the original alarm + # (note the different UID for the new "snooze" alarm): + (3, ("20210302T102500",)), + # When the second "snooze" alarm is triggered, the user decides to dismiss it. + # The client acknowledges both the original alarm and the second "snooze" alarm: + (4, ()), + ] +) +def test_rfc_9074_alarm_times(events, event_index, alarm_times): + """Test the examples from the RFC and their timing. + + Add times use America/New_York as timezone. + """ + a = events[f"rfc_9074_example_{event_index}"].alarms + assert len(a.active) == len(alarm_times) + expected_alarm_times = {vDatetime.from_ical(t, "America/New_York") for t in alarm_times} + computed_alarm_times = {alarm.trigger for alarm in a.active} + assert expected_alarm_times == computed_alarm_times + + +def test_set_to_None(): + """acknowledge_until, snooze_until, set_local_timezone.""" + a = Alarms() + a.set_start(None) + a.set_end(None) + a.set_local_timezone(None) + a.acknowledge_until(None) + a.snooze_until(None) + assert vars(a) == vars(Alarms()) \ No newline at end of file diff --git a/src/icalendar/tests/test_pytz_zoneinfo_integration.py b/src/icalendar/tests/test_pytz_zoneinfo_integration.py index a02aa10d..c93735e7 100644 --- a/src/icalendar/tests/test_pytz_zoneinfo_integration.py +++ b/src/icalendar/tests/test_pytz_zoneinfo_integration.py @@ -90,3 +90,15 @@ def test_cache_is_emptied_when_tzp_is_switched(tzp, timezones, new_tzp_name): tzp.cache_timezone_component(timezones.pacific_fiji) tz2 = tzp.timezone("custom_Pacific/Fiji") assert tz1 is not tz2 + + +def test_invalid_name(tzp): + """Check that the provider name is OK.""" + provider = "invalid_provider" + with pytest.raises(ValueError) as e: + tzp.use(provider) + # f"Unknown provider {provider}. Use 'pytz' or 'zoneinfo'." + message = e.value.args[0] + assert f"Unknown provider {provider}." in message + assert "zoneinfo" in message + assert "pytz" in message diff --git a/src/icalendar/timezone/__init__.py b/src/icalendar/timezone/__init__.py index dc751808..e0da7837 100644 --- a/src/icalendar/timezone/__init__.py +++ b/src/icalendar/timezone/__init__.py @@ -7,8 +7,10 @@ def use_pytz(): """Use pytz as the implementation that looks up and creates timezones.""" tzp.use_pytz() + def use_zoneinfo(): """Use zoneinfo as the implementation that looks up and creates timezones.""" tzp.use_zoneinfo() + __all__ = ["tzp", "use_pytz", "use_zoneinfo"] diff --git a/src/icalendar/timezone/tzp.py b/src/icalendar/timezone/tzp.py index 48cc1e4b..6c24b389 100644 --- a/src/icalendar/timezone/tzp.py +++ b/src/icalendar/timezone/tzp.py @@ -1,12 +1,19 @@ from __future__ import annotations -import datetime -from .. import cal -from typing import Optional, Union + +from typing import TYPE_CHECKING, Optional, Union + +from icalendar.tools import to_datetime + from .windows_to_olson import WINDOWS_TO_OLSON -from .provider import TZProvider -from icalendar import prop -from dateutil.rrule import rrule +if TYPE_CHECKING: + import datetime + + from dateutil.rrule import rrule + + from icalendar import cal, prop + + from .provider import TZProvider DEFAULT_TIMEZONE_PROVIDER = "zoneinfo" @@ -41,10 +48,10 @@ def _use(self, provider:TZProvider) -> None: def use(self, provider:Union[str, TZProvider]): """Switch to a different timezone provider.""" if isinstance(provider, str): - provider = getattr(self, f"use_{provider}", None) - if provider is None: - raise ValueError(f"Unknown provider {provider_name}. Use 'pytz' or 'zoneinfo'.") - provider() + use_provider = getattr(self, f"use_{provider}", None) + if use_provider is None: + raise ValueError(f"Unknown provider {provider}. Use 'pytz' or 'zoneinfo'.") + use_provider() else: self._use(provider) @@ -52,20 +59,20 @@ def use_default(self): """Use the default timezone provider.""" self.use(DEFAULT_TIMEZONE_PROVIDER) - def localize_utc(self, dt: datetime.datetime) -> datetime.datetime: + def localize_utc(self, dt: datetime.date) -> datetime.datetime: """Return the datetime in UTC. If the datetime has no timezone, set UTC as its timezone. """ - return self.__provider.localize_utc(dt) + return self.__provider.localize_utc(to_datetime(dt)) - def localize(self, dt: datetime.datetime, tz: Union[datetime.tzinfo, str]) -> datetime.datetime: + def localize(self, dt: datetime.date, tz: Union[datetime.tzinfo, str]) -> datetime.datetime: """Localize a datetime to a timezone.""" if isinstance(tz, str): tz = self.timezone(tz) - return self.__provider.localize(dt, tz) + return self.__provider.localize(to_datetime(dt), tz) - def cache_timezone_component(self, timezone_component: cal.VTIMEZONE) -> None: + def cache_timezone_component(self, timezone_component: cal.Timezone) -> None: """Cache the timezone that is created from a timezone component if it is not already known. diff --git a/src/icalendar/tools.py b/src/icalendar/tools.py index 896aa7a6..b8b2f7f2 100644 --- a/src/icalendar/tools.py +++ b/src/icalendar/tools.py @@ -1,11 +1,9 @@ -from datetime import datetime -from icalendar.parser_tools import to_unicode -from icalendar.prop import vDatetime -from icalendar.prop import vText -from string import ascii_letters -from string import digits - +from __future__ import annotations import random +from datetime import date, datetime, tzinfo +from string import ascii_letters, digits + +from icalendar.parser_tools import to_unicode class UIDGenerator: @@ -18,18 +16,58 @@ class UIDGenerator: def rnd_string(length=16): """Generates a string with random characters of length. """ - return ''.join([random.choice(UIDGenerator.chars) for _ in range(length)]) + return "".join([random.choice(UIDGenerator.chars) for _ in range(length)]) @staticmethod - def uid(host_name='example.com', unique=''): + def uid(host_name="example.com", unique=""): """Generates a unique id consisting of: datetime-uniquevalue@host. Like: 20050105T225746Z-HKtJMqUgdO0jDUwm@example.com """ + from icalendar.prop import vDatetime, vText host_name = to_unicode(host_name) unique = unique or UIDGenerator.rnd_string() today = to_unicode(vDatetime(datetime.today()).to_ical()) - return vText(f'{today}-{unique}@{host_name}') + return vText(f"{today}-{unique}@{host_name}") + + +def is_date(dt: date) -> bool: + """Whether this is a date and not a datetime.""" + return isinstance(dt, date) and not isinstance(dt, datetime) + + +def is_datetime(dt: date) -> bool: + """Whether this is a date and not a datetime.""" + return isinstance(dt, datetime) + + +def to_datetime(dt: date) -> datetime: + """Make sure we have a datetime, not a date.""" + if is_date(dt): + return datetime(dt.year, dt.month, dt.day) # noqa: DTZ001 + return dt + + +def is_pytz(tz: tzinfo): + """Whether the timezone requires localize() and normalize().""" + return hasattr(tz, "localize") + + +def is_pytz_dt(dt: date): + """Whether the time requires localize() and normalize().""" + return is_datetime(dt) and is_pytz(dt.tzinfo) + + +def normalize_pytz(dt: date): + """We have to normalize the time after a calculation if we use pytz. + + pytz requires this function to be used in order to correctly calculate the + timezone's offset after calculations. + """ + if is_pytz_dt(dt): + return dt.tzinfo.normalize(dt) + return dt + -__all__ = ["UIDGenerator"] +__all__ = ["UIDGenerator", "is_date", "is_datetime", "to_datetime", "is_pytz", "is_pytz_dt", "normalize_pytz"]