Build1 distinct publisher3 min readPublished
A 09:00 opening time is wall clock, not an instant, so in Paris it lands on 07:00Z in August and 08:00Z in January. One availability guide pins that with a test, and the missing spring-forward hour with another.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The interesting code is four lines of integer arithmetic. `wallClock` takes minutes from midnight, pulls out whole days with `Math.floor(m / 1440)`, turns the remainder into hour and minute, builds a luxon `DateTime` with `{ zone }`, then adds the days back [4]. Feed it 1500 and you get one whole day plus a remainder of 60 minutes, so the boundary resolves to 01:00 on the next calendar day in the business's zone [3]. The day carry lands on a value that already knows which zone it lives in, which is why overnight windows and transition days need no branch of their own. The Go edition does the same work through `time.Date(y, mo, d, 0, minute, 0, 0, loc)` [4].
Run the other design on 2026-03-29 in Paris. A fixed base plus 60-minute steps across a 01:00 to 05:00 window gives four candidate starts, one of them local 02:00, an hour the clock skips that night as it jumps to 03:00 [7]. Stepping candidates in the zone instead keeps three, at 00:00Z, 01:00Z and 02:00Z [8]. Four wall-clock hours, three real ones, one slot that has to vanish [2]. The offset-adding engine ships the fourth [9].
The August assertion is the one I would want in a review, because it can only fail in one direction: 07:00Z if the offset was resolved in Paris, 09:00Z if it was resolved on the server [5][6]. The two mappings sit exactly an hour apart all year, which is small enough to read as a rounding artefact in a bug report [1].
Two assertions is the honest scope, and the author says so plainly: the offset case and the spring-forward gap are pinned for Europe/Paris, while the fall-back day when the hour runs twice, and every other zone, follow from the same wall-clock resolution rather than from special-cased code [10]. For that inheritance to hold in your build, a few things have to be true. The availability record has to carry a zone identifier, the way the test's `weekdayAvail('Europe/Paris', MONDAY)` does, rather than a stored offset [13]. Candidate stepping has to happen in local time with the conversion to UTC last [3]. And the test has to pin `now`, as both of these do at 2026-08-01T00:00:00Z and 2026-03-01T00:00:00Z, or the past-slot filter drags the expectation around with the calendar [11]. An offset written into a config row is a fact with an expiry date.
Past that boundary the zone stops paying rent. Slots come out as UTC instants, bookings are stored the same way, and conflict detection reduces to a half-open `[start, end)` overlap on millisecond values [12]. The author's framing of the tradeoff is the part worth arguing with a colleague about: copy the `wallClock` construction and you inherit the property, copy an add-hours-to-UTC approach and there is no test that will catch you [14].
Ranked by verification strength, evidence, and original report placement.
The guide's core assertion is that 09:00 is wall-clock time in a timezone rather than a UTC instant, and that off-by-an-hour slots across zones and a phantom slot on the DST change are the same mistake of treating a wall-clock time as a fixed point in time.
Paris is UTC+2 under DST and UTC+1 otherwise, so 09:00 in a Paris salon is 07:00 UTC in summer and 08:00 UTC in winter; the same "09:00" maps to two different instants depending on the date.
The stated rule that makes the engine correct is to build the window in the business's timezone, resolve the offset there, and only then convert to UTC.
The wallClock helper computes days as Math.floor(minutesFromMidnight / 1440), derives hour and minute from the remainder, calls luxon's DateTime.fromObject({ year, month, day, hour, minute }, { zone }) and then .plus({ days }); the Go edition uses time.Date(y, mo, d, 0, minute, 0, 0, loc) for the same idea.
A test computes slots for Europe/Paris weekday availability on date 2026-08-17 with durationMinutes 60 and asserts slots[0].startAt.toISOString() equals '2026-08-17T07:00:00.000Z'.
Computing slots in UTC or on the server's clock makes that same first slot come out as 09:00Z, an hour wrong silently for every customer.
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 30, 2026
Follow any of these and your For You feed starts watching them — no settings page required.
build
SSE in Go breaks twice before your handler runs: an illegal header, then a 30-second timeout1 distinct publisher
build
TypeScript 7.0 is a build-infrastructure release: re-budget CI, then check your toolchain1 distinct publisher
build
Your meter now runs on someone else's machine: signed receipts, fsync, and failing open1 distinct publisher
build
Zero-Instrumentation Go Tracing Works, But You Are Now Maintaining ABI Offsets1 distinct publisher
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Checkable by hand, vouched for by one author
The load here is carried by facts a reader can verify without the author: Paris really is UTC+2 in August, and both tests arrive complete with date, duration, pinned clock and expected ISO strings, so either can be rerun. What holds the score down is that the engine those assertions exercise is never shown end to end, and one voice supplies all of it.
Nobody says they run this
Not a single deployment, release, download figure or user report appears in this reporting. Two passing assertions in the author's own repository say the technique works; they say nothing about anyone else having adopted it.
The claims stop roughly where the tests do
Rare for a how-to: the guide draws its own boundary, naming the two Paris assertions as all it has and admitting the fall-back day is reasoning rather than coverage. That restraint offsets the one place it overreaches — telling readers that copying the helper hands them the property for every zone — leaving promise and proof about level.
A product domain sits behind the byline
The post names its canonical home as a guides page on a commercial-looking product site, which is the standard shape of developer content marketing. What it does not do is pitch: no product is named in the argument, nothing is gated, and the technique is shown twice over in luxon and in Go, so it survives without the host.
Single voice, verifiable material
Confidence here rests on the subject matter rather than the sourcing. Timezone arithmetic is deterministic and the assertions are complete enough to rerun, so a lone author matters less than it would elsewhere — but with no second publisher, no adoption record and the broadest claim untested, this stays short of firm.