Date/time queries filter and compute over temporal columns — finding records in a range, computing ages/durations, and handling timezones. Testers rely on them constantly because so much test data and so many bugs are time-dependent (expiry, retention, 'last 30 days' logic).
Temporal filtering has recurring pitfalls testers must know. First, the boundary problem: created_at BETWEEN '2026-07-01' AND '2026-07-31' often misses records late on the 31st, because a DATE literal is treated as midnight, so anything after 2026-07-31 00:00:00 is excluded — the robust pattern is created_at >= '2026-07-01' AND created_at < '2026-08-01' (half-open interval). Second, timezones: a timestamp stored in UTC can land on a different calendar day in the user's local zone, so 'orders on July 21' depends on which zone defines the day — a classic off-by-one-day bug. Third, relative ranges: 'last 30 days' should be computed from the current time (CURRENT_DATE - INTERVAL '30 days') rather than hardcoded, or tests rot. Databases differ in date syntax (INTERVAL, DATE_SUB, DATEADD), and functions like DATE_TRUNC, EXTRACT and AGE help bucket and compute durations. For testers, deliberately crafting boundary dates (exactly 30 days ago, the last second of a period) is where date bugs are caught.
A 'monthly report' test using created_at BETWEEN '2026-07-01' AND '2026-07-31' kept dropping orders placed on the evening of the 31st. Switching to created_at >= '2026-07-01' AND created_at < '2026-08-01' captured the full month, fixing the undercount.
-- ROBUST month filter: half-open interval captures the whole final day
SELECT id, created_at FROM orders
WHERE created_at >= '2026-07-01'
AND created_at < '2026-08-01';
-- FRAGILE: BETWEEN with date literals misses most of the 31st
-- WHERE created_at BETWEEN '2026-07-01' AND '2026-07-31';
-- Relative window: last 30 days, computed from now (Postgres syntax)
SELECT id FROM orders
WHERE created_at >= CURRENT_DATE - INTERVAL '30 days';
-- Bucket orders per day; find records older than a retention limit
SELECT DATE_TRUNC('day', created_at) AS day, COUNT(*)
FROM orders GROUP BY 1 ORDER BY 1;
SELECT id FROM sessions
WHERE created_at < CURRENT_TIMESTAMP - INTERVAL '90 days'; -- retention checkScenario: A test for a 'transactions this month' report filters WHERE created_at BETWEEN '2026-07-01' AND '2026-07-31'. It passes in CI but users report that transactions made on the 31st are missing from the report, and separately, some transactions appear under the wrong day. Diagnose both issues.