Every day, a report runs: "what did each store sell yesterday?" One of the stores is in Lagos, the other in London. The report showed both stores as having zero sales for the last two hours of the day: wrong numbers, every day, in production. Here's the conversion pattern that fixed it.

The Problem

You store your timestamps in UTC. Django recommends it, Postgres defaults to it, and it keeps your data unambiguous. Order 582 was placed at 2025-03-10 23:15:00+00:00. Clean, portable, no ambiguity.

But a report that asks for "Tuesday's orders" needs to know what Tuesday means. Tuesday in Lagos starts at 11 PM Monday UTC. Tuesday in London starts at midnight UTC. If your reporting query uses UTC midnight for everyone, orders placed between 11 PM and midnight UTC get assigned to the wrong day for every store east of GMT.

The fix is deceptively simple: each store knows its timezone, and the reporting query converts the store's local day-bounds into a UTC range before filtering. But there's a landmine in the conversion, and it's one that only fires in production: