The Last Day Is Missing

orders.ordered_at is timestamptz and there is a B-tree index on it. This monthly count is quietly low:

SELECT count(*) FROM orders
WHERE ordered_at BETWEEN '2026-01-01' AND '2026-01-31';

Which replacement is both correct and able to use that index as an access predicate?

A
WHERE ordered_at BETWEEN '2026-01-01' AND '2026-01-31 23:59:59'
B
WHERE ordered_at >= DATE '2026-01-01'
  AND ordered_at <  DATE '2026-02-01'
C
WHERE date_trunc('month', ordered_at) = DATE '2026-01-01'
D
WHERE ordered_at::date BETWEEN DATE '2026-01-01' AND DATE '2026-01-31'