From 672858b2bd881780c5dbe14fa49129ca274ed4e4 Mon Sep 17 00:00:00 2001 From: Sasha Mitchell Date: Thu, 1 Oct 2026 22:09:16 +0700 Subject: [PATCH] Keep the minutes of a four-digit W3C timezone offset. +0530 was read as +05:00 because the minute slice assumed a colon. --- changelog.d/20261001_w3dtf_hhmm.rst | 7 +++++++ feedparser/datetimes/w3dtf.py | 11 +++++++++-- tests/test_date_parsers.py | 10 ++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 changelog.d/20261001_w3dtf_hhmm.rst diff --git a/changelog.d/20261001_w3dtf_hhmm.rst b/changelog.d/20261001_w3dtf_hhmm.rst new file mode 100644 index 00000000..cab0c04c --- /dev/null +++ b/changelog.d/20261001_w3dtf_hhmm.rst @@ -0,0 +1,7 @@ +Fixed +----- + +* Keep the minutes of a four-digit timezone offset in W3C dates. + + ``2003-12-31T10:14:55+0530`` was read as +05:00. + ``+05:30`` is unchanged. diff --git a/feedparser/datetimes/w3dtf.py b/feedparser/datetimes/w3dtf.py index 96a68cf6..fc7022f1 100644 --- a/feedparser/datetimes/w3dtf.py +++ b/feedparser/datetimes/w3dtf.py @@ -99,9 +99,16 @@ def _parse_date_w3dtf(datestr): # minutes and seconds, if missing, will default to 0. time.extend(["0"] * (3 - len(time))) if parts[2][:1] in ("-", "+"): + rest = parts[2][1:] try: - tzhour = int(parts[2][1:3]) - tzmin = int(parts[2][4:]) + # ``+0530`` has no colon, so the minutes are the last two digits. + # ``+05:30`` keeps the colon between the hours and the minutes. + if len(rest) == 4 and rest.isdigit(): + tzhour = int(rest[:2]) + tzmin = int(rest[2:]) + else: + tzhour = int(rest[:2]) + tzmin = int(rest[3:]) except ValueError: return None if parts[2].startswith("-"): diff --git a/tests/test_date_parsers.py b/tests/test_date_parsers.py index 25a73fe3..725c2b4b 100644 --- a/tests/test_date_parsers.py +++ b/tests/test_date_parsers.py @@ -254,6 +254,16 @@ def test_year_10000_date(): "2003-12-31T18:14:55+08:00", (2003, 12, 31, 10, 14, 55, 2, 365, 0), ), # Tokyo timezone + ( + _parse_date_w3dtf, + "2003-12-31T10:14:55+0530", + (2003, 12, 31, 4, 44, 55, 2, 365, 0), + ), # +hhmm, same offset as +05:30 + ( + _parse_date_w3dtf, + "2003-12-31T10:14:55-0530", + (2003, 12, 31, 15, 44, 55, 2, 365, 0), + ), # -hhmm, same offset as -05:30 ( _parse_date_w3dtf, "2007-04-23T23:25:47.538+10:00",