Batu Lab NotesPractical developer guides

Group timestamps by calendar day in UTC

By Batu · English technical notes

Also published in our Blogger archive.

A timestamp’s calendar day depends on the time zone used to read it. If reporting is defined in UTC, convert every aware timestamp to UTC before taking .date(). The example parses three offset-bearing ISO 8601 timestamps, converts each with astimezone(timezone.utc), and appends it to a defaultdict(list) keyed by the resulting UTC date. Although the source strings show different local dates and offsets, all three describe moments on 2026-05-02 in UTC, so the output reports one group containing three items.

The assertion verifies the synthetic group count; it does not verify input provenance, timestamp parsing policy, or a reporting requirement. Do not simply call .date() on each original value: that groups by its attached local offset instead. Also reject or define a policy for naive datetimes before this step, because they lack the offset needed for an unambiguous UTC conversion.

datetime.fromisoformat() was added in Python 3.7, and the example uses only standard-library datetime, timezone, and collections.defaultdict. ISO parsing support broadened in Python 3.11, but these complete offset forms work on Python 3.7+. This technique groups by UTC’s Gregorian calendar; it is not a substitute for grouping by a customer’s local reporting zone.

See Python datetime documentation for aware datetimes and astimezone(), plus the defaultdict documentation for automatic list creation.

AI-assistance disclosure: This article was drafted with AI assistance and should be reviewed in its application context.

from collections import defaultdict
from datetime import date, datetime, timezone

values = [
    "2026-05-01T23:30:00-04:00",
    "2026-05-02T00:15:00+00:00",
    "2026-05-02T09:30:00+09:00",
]

groups = defaultdict(list)
for value in values:
    stamp = datetime.fromisoformat(value)
    groups[stamp.astimezone(timezone.utc).date()].append(stamp)

assert {day: len(items) for day, items in groups.items()} == {
    date(2026, 5, 2): 3
}

for day in sorted(groups):
    print(day.isoformat(), len(groups[day]))
2026-05-02 3