I have a table with a field called recordTime
of type timestamp without time zone
. I want to select todays records only (i.e. since midnight). The records are sourced globally and arrive as UTC, so I need to select records based on midnight UTC.
There seems to be a myriad of ways of doing this including…
WHERE date_trunc('day', recordTime) = current_date ;
WHERE date_trunc('day', recordTime) = date_trunc('day', current_date at time zone 'utc')
WHERE date_trunc('day', recordTime) = date_trunc('day', current_timestamp at time zone 'utc')
WHERE recordTime >= '17-May-2024 00:00:00'
Which of these is best practice – or maybe a different method entirely? (bearing in mind that performance seems similar in all cases)
2
Answers
Today starts at midnight 00:00 and ends "tomorrow" also at midnight. Just use today and tomorrow:
It’s fairly straight forward and easy to read and understand. You can even do some additional interval calculations on these values, if needed.
I don’t know if this is best practice, but it has the advantage of being explicit about its conversions. It also avoids the gotcha of accidentally matching midnight the next day.
You can shorten it to:
Incorrect. This will match every recordTime after May 17th, including May 18th, May 19th, etc.
You’d instead write…
This will match 17-May-2024 00:00 and will not match 18-May-2024 00:00.
You have to input the date manually, but that’s a simple matter if you’re running the query from a program.
Watch out using
between
. For example,where recordTime between '17-May-2024'::date and '18-May-2024'::date
. This will match both dates.where recordTime between '17-May-2024'::date and '17-May-2024'::date
is correct, but odd. It’s better to write it out long-hand.current_date
is the date according to the current time zone, but it has no time zone information, so that’s no good here. Also don’t use synonyms liketoday
andtomorrow
.Finally, the best thing for performance is to ensure
recordTime
is indexed.