A Berlin user typed 09:00 and we started two different clocks
- engineering
- deadlines
- timezones
We shipped a bug where the same typed time produced two different legal deadlines depending on which screen you typed it into. It is the kind of bug that is completely invisible in testing, because everything is consistent when your laptop and your server agree, and every CI runner in the world agrees with a UTC server. Here is the shape of it, and the test that would have caught it.
The short answer
An HTML datetime-local input has no timezone offset in its value. 2026-09-10T09:00
means whatever zone the code that parses it happens to be running in. Our incident form
parsed it on the server, which is UTC. Our triage form parsed it in the browser, which
is the user's own zone. A Berlin user typing 09:00 got 09:00Z from one screen and
07:00Z from the other — two hours apart, in opposite directions, on the field that
starts the twenty-four-hour clock.Art. 14(2)
Wall-clock time
A date and time with no offset attached: what a clock on a wall shows, in some zone the
value itself does not name. 2026-09-10T09:00 is wall-clock. 2026-09-10T09:00Z and
2026-09-10T09:00+02:00 are instants, because each of them identifies exactly one
moment. A datetime-local input always produces the first kind.
Why it survives every reasonable test
The damage requires a disagreement between two parsers, and the natural way to test a form is to exercise one at a time. Each screen was internally consistent and each screen's tests passed. The asymmetry only appears when a value written by one is read back by the other, in a zone that is not UTC — which is to say, in production, in Europe, which is the only place this product is used.
It is also silent by construction. There is no exception, no malformed value, nothing in a log. A deadline appears; it is simply the wrong deadline, by an amount equal to the user's offset, and it is wrong in the direction that makes it look fine.
The test that finds it
Two assertions, and neither needs a browser.
Parse a fixed wall-clock string in at least two zones and assert the resulting instants
differ by exactly the expected offset. Then parse it in a zone that observes daylight
saving, on a date either side of the transition, and assert the offset changes — because
a fixed +02:00 constant is the second version of this bug and it fails twice a year.
Pin the test runner's TZ, or you are testing your own laptop.
If you want a single canary: take the value your form produces, round-trip it through whatever your API stores, format it back into the user's zone, and assert you got the same digits the user typed. That catches every variant of this, including the ones involving a database column that quietly dropped the zone.
The fix is at the boundary, not downstream
Everything downstream of that input was already careful. The deadline arithmetic works in UTC instants throughout and converts only for display, which makes it immune to daylight saving by construction — add twenty-four hours to an instant and you get an instant, whatever the calendar in between was doing.
None of that care helps if the instant entering it was wrong. So the rule we settled on is that a wall-clock string is converted exactly once, at the edge, in a zone the code states explicitly rather than inherits. Inside that boundary there are only instants.
Two related traps we hit on the way. Most date libraries' helpers operate in the
runtime's local zone — adding a month with one of them on a server in a non-UTC zone
silently shifts the deadline, so calendar arithmetic has to be written against UTC
explicitly. And Intl is the thing that actually carries the zone database, which
means the direction you format with and the direction you parse with can be made to
agree, rather than being two independent guesses.
Why write this up
Because a compliance product is a strange thing to publish clock bugs about, and publishing them anyway is most of the argument for trusting one. The deadline is the product. If we found a two-hour error in how a deadline begins, the useful thing to do with it is describe the class of bug well enough that somebody else finds theirs.
Every deadline this product computes is on the timeline, including the one that does not run from awareness at all.
Not sure whether this applies to you?
This produces evidence, timelines and drafts. It is not legal advice, and you remain the party responsible for reporting.