diff --git a/README.md b/README.md index 0222978..8eae851 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,28 @@ events: In this meeting we will ... ``` +## Timezones + +The event timezone can be specified in three ways (in reverse order of precedence): + +1. Using the `timezone: ...` field, as shown above under "Syntax". +2. Adding it to an individual event: + + ```yaml + - summary: My event + timezone: US/Pacific + ``` + +3. By specifying a timezone in the event start time: + + ``` + 2021-09-21 15:00:00 +07:00 + ``` + Valid timezones are listed at https://datetime.app/iana-timezones +If no timezone is set, we default to UTC. + ## Contributing Contributions are welcomed! This project is still in active development diff --git a/pyproject.toml b/pyproject.toml index 2826c97..f36e06d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,6 +89,7 @@ ignore = [ "ARG001", # Unused function argument "PT012", # `pytest.raises()` block "PLW0129", # Asserting on a non-empty string literal will always pass + "SIM108", # Use ternary operator instead of `if`-`else`-block ] [tool.pytest.ini_options] diff --git a/tests/test_events.py b/tests/test_events.py index d535c4c..389c055 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -173,3 +173,19 @@ def test_events_with_multiple_timezones(): assert events[1].begin.tzname() in ("UTC", "Coordinated Universal Time") assert events[2].begin.tzname() == "PDT" assert events[3].begin.tzname() == "PST" + + +def test_events_without_timezone(): + f = io.BytesIO(b""" + name: Default Timezone + events: + - summary: Meeting A + begin: 2025-09-02 17:00:00 + duration: { minutes: 60 } + - summary: Meeting B + begin: 2025-12-01 09:00:00 + end: 2025-12-01 10:00:00 + """) + events, _ = files_to_events([f]) + assert events[0].begin.tzname() in ("UTC", "Coordinated Universal Time") + assert events[1].begin.tzname() in ("UTC", "Coordinated Universal Time") diff --git a/yaml2ics.py b/yaml2ics.py index f3a42bc..2227f1d 100644 --- a/yaml2ics.py +++ b/yaml2ics.py @@ -52,12 +52,12 @@ def gettz(tzname: str) -> datetime.tzinfo: # This function can be used to add a list of e.g. exception dates (EXDATE) or # recurrence dates (RDATE) to a reoccurring event def add_recurrence_property( - event: ics.Event, property_name, dates: map, tz: datetime.tzinfo = None + event: ics.Event, property_name, dates: map, tz: datetime.tzinfo = dateutil.tz.UTC ): event.extra.append( ics.ContentLine( name=property_name, - params={"TZID": [str(ics.Timezone.from_tzinfo(tz))]} if tz else None, + params={"TZID": [str(ics.Timezone.from_tzinfo(tz))]}, value=",".join(dates), ) ) @@ -68,6 +68,8 @@ def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = None) -> ics.Event: repeat = d.pop("repeat", None) ics_custom = d.pop("ics", None) + if tz is None: + tz = dateutil.tz.UTC if "timezone" in d: tzname = d.pop("timezone") tz = gettz(tzname)