Time & dates
Concept  ·  SQL & Querying

Use [start, end) for timestamp ranges — BETWEEN loses the last day's daytime (P01 atom, promoted to habit).

A timestamp range is safest written half-open: >= start AND < next_start. That keeps the whole final day and excludes the first instant of the next period. BETWEEN, being closed on the right, stops at the month-end's midnight and loses that day's daytime.

See it break
sessions
idended
12024-06-30 14:00
22024-07-01 00:00
32024-06-10 09:00
The trap
SELECT
  id
FROM
  sessions
WHERE
  ended BETWEEN TIMESTAMP '2024-06-01'
  AND TIMESTAMP '2024-06-30'
ORDER BY
  id;
The fix
SELECT
  id
FROM
  sessions
WHERE
  ended >= TIMESTAMP '2024-06-01'
  AND ended < TIMESTAMP '2024-07-01'
ORDER BY
  id;
The trap
3
The fix
1
3

The June parking report drops every session that ended after midnight on the 30th — BETWEEN's closed upper bound cuts the last day short.

The rule

Write ranges as [start, next_start) with >= and <, generated one period at a time, so no day is ever half-counted.

ts >= DATE '2024-03-01' AND ts < DATE '2024-04-01'
Shows up elsewhere
BETWEEN on timestamps — the midnight trap
Try one →Prove it in practice →