From a2c593a0d2025f1e0e5b72954710ae1cbecbdd86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 29 Jul 2025 11:32:43 -0700 Subject: [PATCH 01/10] BUG: defaulting to UTC tz rather than to None --- yaml2ics.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yaml2ics.py b/yaml2ics.py index f3a42bc..ee58dc8 100644 --- a/yaml2ics.py +++ b/yaml2ics.py @@ -52,18 +52,18 @@ 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), ) ) -def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = None) -> ics.Event: +def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = dateutil.tz.UTC) -> ics.Event: d = event_yaml repeat = d.pop("repeat", None) ics_custom = d.pop("ics", None) From 95b8a7d81a407050de09365fdeccbd21cf891885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 29 Jul 2025 12:14:42 -0700 Subject: [PATCH 02/10] BUG: again, default tz to UTC --- yaml2ics.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yaml2ics.py b/yaml2ics.py index ee58dc8..26b14f1 100644 --- a/yaml2ics.py +++ b/yaml2ics.py @@ -184,6 +184,8 @@ def files_to_events(files: list) -> (ics.Calendar, str): tz = calendar_yaml.get("timezone", None) if tz is not None: tz = gettz(tz) + else: + tz = dateutil.tz.UTC if "include" in calendar_yaml: included_events, _name = files_to_events( os.path.join(os.path.dirname(f), newfile) From a4405a86e7a2005e9d1a6e180c5a32b7eb645d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 29 Jul 2025 12:42:57 -0700 Subject: [PATCH 03/10] MAINT: ignore ruff --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) 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] From fa9a56cab80c38370c2fd22e1dbadda43a33870c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 29 Jul 2025 12:46:04 -0700 Subject: [PATCH 04/10] MAINT: this really is becoming ridiculous --- yaml2ics.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/yaml2ics.py b/yaml2ics.py index 26b14f1..be7822b 100644 --- a/yaml2ics.py +++ b/yaml2ics.py @@ -63,7 +63,9 @@ def add_recurrence_property( ) -def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = dateutil.tz.UTC) -> ics.Event: +def event_from_yaml( + event_yaml: dict, tz: datetime.tzinfo = dateutil.tz.UTC +) -> ics.Event: d = event_yaml repeat = d.pop("repeat", None) ics_custom = d.pop("ics", None) From 765d4731c13eb9ada9da68ea896e904d7b98c553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 2 Dec 2025 19:45:49 -0800 Subject: [PATCH 05/10] Revert "BUG: again, default tz to UTC" This reverts commit 95b8a7d81a407050de09365fdeccbd21cf891885. --- yaml2ics.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/yaml2ics.py b/yaml2ics.py index be7822b..663bc0d 100644 --- a/yaml2ics.py +++ b/yaml2ics.py @@ -186,8 +186,6 @@ def files_to_events(files: list) -> (ics.Calendar, str): tz = calendar_yaml.get("timezone", None) if tz is not None: tz = gettz(tz) - else: - tz = dateutil.tz.UTC if "include" in calendar_yaml: included_events, _name = files_to_events( os.path.join(os.path.dirname(f), newfile) From e9fdbc64412408ce1cc469353497a3892372cfcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 2 Dec 2025 19:59:16 -0800 Subject: [PATCH 06/10] TST: adding test for defaulting to UTC --- tests/test_events.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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") From 00216b5aff9fef60d575dbfbd90c18eb27dc4832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 2 Dec 2025 19:59:38 -0800 Subject: [PATCH 07/10] Revert "Revert "BUG: again, default tz to UTC"" This reverts commit 765d4731c13eb9ada9da68ea896e904d7b98c553. --- yaml2ics.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yaml2ics.py b/yaml2ics.py index 663bc0d..be7822b 100644 --- a/yaml2ics.py +++ b/yaml2ics.py @@ -186,6 +186,8 @@ def files_to_events(files: list) -> (ics.Calendar, str): tz = calendar_yaml.get("timezone", None) if tz is not None: tz = gettz(tz) + else: + tz = dateutil.tz.UTC if "include" in calendar_yaml: included_events, _name = files_to_events( os.path.join(os.path.dirname(f), newfile) From 765a076380b05f43d45b01b6c1b1dba1358d8846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 2 Dec 2025 20:54:22 -0800 Subject: [PATCH 08/10] Revert "Revert "Revert "BUG: again, default tz to UTC""" This reverts commit 00216b5aff9fef60d575dbfbd90c18eb27dc4832. --- yaml2ics.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/yaml2ics.py b/yaml2ics.py index be7822b..663bc0d 100644 --- a/yaml2ics.py +++ b/yaml2ics.py @@ -186,8 +186,6 @@ def files_to_events(files: list) -> (ics.Calendar, str): tz = calendar_yaml.get("timezone", None) if tz is not None: tz = gettz(tz) - else: - tz = dateutil.tz.UTC if "include" in calendar_yaml: included_events, _name = files_to_events( os.path.join(os.path.dirname(f), newfile) From c5d4b82468107ea8a7bbb976901c83549555c435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 2 Dec 2025 21:11:34 -0800 Subject: [PATCH 09/10] Changing the default --- yaml2ics.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yaml2ics.py b/yaml2ics.py index 663bc0d..2227f1d 100644 --- a/yaml2ics.py +++ b/yaml2ics.py @@ -63,13 +63,13 @@ def add_recurrence_property( ) -def event_from_yaml( - event_yaml: dict, tz: datetime.tzinfo = dateutil.tz.UTC -) -> ics.Event: +def event_from_yaml(event_yaml: dict, tz: datetime.tzinfo = None) -> ics.Event: d = event_yaml 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) From 344bdf0aac9ae58d2eef975491f029db2d94bf00 Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Wed, 3 Dec 2025 17:51:33 -0800 Subject: [PATCH 10/10] Document UTC default --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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