07 · Statements

Select transactions by the account calendar month

Select a month's transactions using midnight in the account's own time zone, converted to UTC.

Python · zoneinfomedium

What the hardened grader checks

Solutions

Reference

reference

Converts the local month boundaries to UTC instants and compares against them.

Naive: accepted (3/3)Hardened: accepted (19/19)

Alternative

alt_valid

Selects via local calendar membership rather than comparing UTC interval bounds.

Naive: accepted (3/3)Hardened: accepted (19/19)

wrong_fixed_offset

Keeps a standard-time offset throughout the year.

Naive: accepted (3/3)Hardened: rejected (16/19)

wrong_offset_sign

Adds each local boundary's UTC offset instead of subtracting it when computing the UTC interval.

Naive: rejected (2/3)Hardened: rejected (14/19)

wrong_utc_month

Uses UTC calendar months for every account.

Naive: rejected (2/3)Hardened: rejected (14/19)

Held-out solutions

Tests × solutions

Each row groups a test’s parameterized cases; any failing case marks the row as Fail. * marks a wrong solution’s declared must_fail test.

Hardened · 19 recorded cases · 8 test rows
TestStarterReferenceAlternativefixed offsetoffset signutc month
Local midnight boundariesFailPassPassPassFail *Fail *
Microsecond boundaryPassPassPassPassPassPass
Dst monthsFailPassPassFail *Fail *Fail
Naive and instant orderFailPassPassPassPassPass
Non none tzinfo with no offset is naivePassPassPassPassPassPass
Thirteen month partitionPassPassPassPassPassPass
Invalid zone month or year raisesFailPassPassPassPassPass
Supported year range edgesPassPassPassPassPassPass
Naive grader
Naive · 3 recorded cases · 3 test rows
TestStarterReferenceAlternativefixed offsetoffset signutc month
Midmonth utcPassPassPassPassPassPass
Ticket worked example toronto januaryFailPassPassPassFailFail
Naive timestamp rejectedPassPassPassPassPassPass

The ticket

Ticket: monthly statements follow the account timezone

statements.period.period_bounds(account_tz:str,year:int,month:int)->tuple[datetime,datetime] returns aware UTC instants for a half-open interval. select(txns:list[Txn],account_tz,year,month) returns transaction ids sorted by instant, then lexicographic id. Frozen Txn(id:str,at:datetime) is public. IDs are unique and timestamps may have arbitrary aware offsets and microseconds.

The period is the calendar month in the account's IANA timezone: local 00:00 on day 1 inclusive through local 00:00 on day 1 of the next month exclusive, converted to UTC using zoneinfo. An unknown time zone name, a non-int (or bool) year or month, a month outside 1-12 or a year outside 1900-2098 raises ValueError from both functions. Daylight saving rules apply independently to both endpoints. Each input timestamp must be aware with a non-None utcoffset, otherwise select raises ValueError, even when that transaction would be outside the month. Do not mutate inputs. Empty input returns []. Money is not part of this interface.

Worked example: for an America/Toronto account, January 2026 is the interval [2026-01-01T05:00:00Z, 2026-02-01T05:00:00Z) (Toronto is UTC-5 in January). A transaction at 2026-02-01T04:30:00Z is 23:30 on 31 January in Toronto, so it belongs to January; one at 2026-02-01T05:30:00Z is 00:30 on 1 February and belongs to February. So selecting January 2026 for Txn("a", 2026-02-01T04:30Z) and Txn("b", 2026-02-01T05:30Z) returns ["a"].

Run from starter: python -m pytest tests -q. The records are entirely synthetic.

Source