Your till thinks the day ends at 1am
From late March to late October, British clocks are an hour ahead of the clock most software counts in. If your POS works out "today" the easy way, the drawer figure it shows you is wrong twice a day — once by an hour of takings, and once by a whole day of them.
Almost every system stores the time an order happened in UTC. That is the right thing to do — it is the same everywhere and it never goes backwards. The mistake is what comes next: working out which orders happened today by asking which of them carry today's UTC date.
For five months of the year, in Britain, those are the same question. For the other seven they are not, and nothing tells you when you crossed over.
The hour that goes missing
It is a Friday in September. Your kitchen serves until 2am. Between midnight and 1am you take £25 in cash.
Those orders happened on Saturday as far as anybody in the building is concerned. But British Summer Time is an hour ahead of UTC, so the timestamp says 23:30 on Friday. Ask for "orders whose date is today" on Saturday and they are not there. The drawer holds £25 that the screen does not expect.
Which sounds harmless, until you notice what it does to a count. A drawer that is £25 short from something going wrong now reads as balanced, because there is an extra £25 sitting in it that nobody is counting. The error hides a real one of the same size, and it does it every single day until the clocks go back.
And the day that arrives twice
Now run the same screen at half past midnight — which is exactly when a late venue cashes up.
The wall clock says Saturday. UTC still says Friday. So "today" means Friday, and the figure you are shown is everything you took on Friday from 1am onwards, plus the half hour since midnight. You are counting a drawer against a day and a half of sales.
This one is loud — the number is obviously far too big and somebody rings support. The missing-hour version is the dangerous one, because it is small, plausible, and always points the same way.
How to check your own
You do not need anybody's source code. Two tests, five minutes:
One. Between now and October, take an order after midnight and before 1am. Then look at your day's sales, or your expected drawer, the next morning. If that order is not in it, you have this.
Two. Open the same figure at 00:30 and write it down. Open it again at 01:30. If it dropped by a day's takings in the hour between, you have this. A real day's total does not fall.
Then ask the harder version of the question: does anything on this screen tell me which midnight it used? A figure labelled "today" that will not say when today started cannot be checked by the person holding the cash.
What we changed
The register's expected-drawer figure now asks for the day the venue is having, not the day UTC is having. It works that out from the real timezone rather than by adding an hour — because adding an hour is right most of the year and wrong on the two days a year that are hardest to reason about, when one day is 23 hours long and another is 25. Those two days are in the tests.
And the figure now says what window it used, so the answer to "which midnight?" is on the screen rather than in somebody's head.
We have not finished. The same easy shortcut appears in other reports in our own product, and we are working through them. We are saying so here rather than waiting until it is all done, because the check above works on our screens as well as anybody else's, and a bug you can test for is worth more to you than a claim that there are none.
What the register does with cash is on the register page; signed counts and the reporting round them are on the stock and reporting page.