Postgresql – Time interval is returning all records or no records

datetimepostgresqlwhere

I am trying to run a query to return records in the last 24 hours and following the instructions here: time interval tutorial

After running the query at 18:30 UTC, my query looks as follows:

RETURN QUERY
        SELECT 
            h.heartbeat_time
            ,h.message
            ,h.rec_created_by_user_id
        FROM backup.heartbeat AS h
        WHERE h.heartbeat_time  >= NOW() - INTERVAL '30 MINUTE';

and the return:

heartbeat_time     |message                                       
-------------------|----------------------------------------------
2019-12-19 17:46:31|some random aws event                         
2019-12-19 17:48:17|{¶                                            
2019-12-19 17:48:47|{"id": "89d1a02d-5ec7-412e-82f5-13505f849b41",
2019-12-19 18:09:23|{"id": "89d1a02d-5ec7-412e-82f5-13505f849b41",
2019-12-19 18:10:11|{"id": "89d1a02d-5ec7-412e-82f5-13505f849b41",
2019-12-19 18:10:48|{"id": "89d1a02d-5ec7-412e-82f5-13505f849b41",
2019-12-19 18:11:14|{"id": "89d1a02d-5ec7-412e-82f5-13505f849b41",

I would expect the anything older than 18:00 UTC to now show up, but 17:46-48 still shows up.

According to the provided link and many others, this is the correct syntax. Is there something I am missing?

Best Answer

When doing operations on dates where server timeszone and the date in table is in different times zones can be counter intuitive ..

here is the query demonstrating what is going on notice that interval can recast to the local time zone...

This is one of the reason to cast all the date fields to a specific timezone to avoid weirdness like this

select dd,  
  dd >= timestamp '2019-12-19 18:30'  at time zone 'UTC'  - interval '30   minute', 
  (timestamp '2019-12-19 18:30'  at time zone 'UTC') - interval '30 minute',
  dd >= (timestamp '2019-12-19 18:30'  at time zone 'UTC'  - interval '30 minute')
  at time zone 'UTC',
  ((timestamp '2019-12-19 18:30'  at time zone 'UTC') - interval '30 minute' ) at
    time zone 'UTC'

from (select 
 '2019-12-19 17:46:31'::timestamp as dd 
  union
  select  '2019-12-19 17:48:17'::timestamp 
   union
  select '2019-12-19 17:48:47'::timestamp
   union
  select '2019-12-19 18:09:23'::timestamp
   union
  select '2019-12-19 18:10:11'::timestamp
   union
  select 2019-12-19 18:10:48'::timestamp
   union
  select '2019-12-19 18:11:14'::timestamp) ff

"2019-12-19 18:09:23"   true    "2019-12-19 13:00:00-05"    true    "2019-12-19 18:00:00"
"2019-12-19 17:46:31"   true    "2019-12-19 13:00:00-05"    false   "2019-12-19 18:00:00"
"2019-12-19 17:48:47"   true    "2019-12-19 13:00:00-05"    false   "2019-12-19 18:00:00"
"2019-12-19 18:11:14"   true    "2019-12-19 13:00:00-05"    true    "2019-12-19 18:00:00"
"2019-12-19 18:10:48"   true    "2019-12-19 13:00:00-05"    true    "2019-12-19 18:00:00"
"2019-12-19 18:10:11"   true    "2019-12-19 13:00:00-05"    true    "2019-12-19 18:00:00"
"2019-12-19 17:48:17"   true    "2019-12-19 13:00:00-05"    false   "2019-12-19 18:00:00"