The reconciliation report balanced on my machine and showed a gap on the server. Same code, same snapshot, same day.
I spent hours inside the matcher, sure I had broken something in how payments get attributed to requisites. The matcher was fine.
The job built its own window. It asked the process what "yesterday" meant: my laptop answered in my local timezone, the server answered in UTC. Payments that settled in the late-evening band landed on one side of the boundary for me and on the other side for production. Nothing was lost, and the amounts showed up in the next day's run.
That self-healing part is what actually cost me. A gap that disappears by morning teaches operators that small gaps are noise. Once people start eyeballing a money report and deciding which rows to ignore, the report has stopped doing its job, and no code change buys that trust back cheaply.
So now no process that touches money gets to ask the environment what day it is. The period is an explicit parameter, passed in and stored next to the result, so every figure can be recomputed with the exact boundary that produced it. Instants are UTC. The business day is a property of the product (the settlement day that was agreed on), not of whichever box the worker woke up on. Dev environments run UTC too, so nobody gets a comfortable clock. And there is one test with a payment sitting deliberately a minute on each side of the cutoff.
If you run daily financial reports, I would want to know where you pin the business day: the bank's settlement day, the provider's timestamp, or your own ingest time...