[formatter] fix local DST datetime offsets for ':O'

'O' would get the *current* local UTC offset and apply it to all
'datetime' objects it gets applied to.
This would result in a wrong offset if the current offset includes
DST and the target 'datetime' does not or vice-versa.

'O' now determines the correct local UTC offset while respecting DST for
each individual 'datetime'.
pull/5372/head
Mike Fährmann 6 months ago
parent e8c0a09e3f
commit ddb2edfd32
No known key found for this signature in database
GPG Key ID: 5680CA389D365A88

@ -375,18 +375,18 @@ def _parse_offset(format_spec, default):
fmt = _build_format_func(format_spec, default)
if not offset or offset == "local":
is_dst = time.daylight and time.localtime().tm_isdst > 0
offset = -(time.altzone if is_dst else time.timezone)
def off(dt):
local = time.localtime(util.datetime_to_timestamp(dt))
return fmt(dt + datetime.timedelta(0, local.tm_gmtoff))
else:
hours, _, minutes = offset.partition(":")
offset = 3600 * int(hours)
if minutes:
offset += 60 * (int(minutes) if offset > 0 else -int(minutes))
offset = datetime.timedelta(0, offset)
offset = datetime.timedelta(seconds=offset)
def off(obj):
return fmt(obj + offset)
def off(obj):
return fmt(obj + offset)
return off

@ -31,8 +31,9 @@ class TestFormatter(unittest.TestCase):
"h": "<p>foo </p> &amp; bar <p> </p>",
"u": "&#x27;&lt; / &gt;&#x27;",
"t": 1262304000,
"dt": datetime.datetime(2010, 1, 1),
"ds": "2010-01-01T01:00:00+0100",
"dt": datetime.datetime(2010, 1, 1),
"dt_dst": datetime.datetime(2010, 6, 1),
"name": "Name",
"title1": "Title",
"title2": "",
@ -236,19 +237,18 @@ class TestFormatter(unittest.TestCase):
self._run_test("{ds:D%Y-%m-%dT%H:%M:%S%z/O1}", "2010-01-01 01:00:00")
self._run_test("{t!d:O2}", "2010-01-01 02:00:00")
orig_daylight = time.daylight
orig_timezone = time.timezone
orig_altzone = time.altzone
try:
time.daylight = False
time.timezone = -3600
self._run_test("{dt:O}", "2010-01-01 01:00:00")
time.timezone = 7200
self._run_test("{dt:Olocal}", "2009-12-31 22:00:00")
finally:
time.daylight = orig_daylight
time.timezone = orig_timezone
time.altzone = orig_altzone
def test_offset_local(self):
ts = self.kwdict["dt"].replace(tzinfo=datetime.UTC).timestamp()
offset = time.localtime(ts).tm_gmtoff
dt = self.kwdict["dt"] + datetime.timedelta(seconds=offset)
self._run_test("{dt:O}", str(dt))
self._run_test("{dt:Olocal}", str(dt))
ts = self.kwdict["dt_dst"].replace(tzinfo=datetime.UTC).timestamp()
offset = time.localtime(ts).tm_gmtoff
dt = self.kwdict["dt_dst"] + datetime.timedelta(seconds=offset)
self._run_test("{dt_dst:O}", str(dt))
self._run_test("{dt_dst:Olocal}", str(dt))
def test_sort(self):
self._run_test("{l:S}" , "['a', 'b', 'c']")

Loading…
Cancel
Save