Goal: To receive all articles created in 2012-08-19 (in local time).
'+01:00'
(like you use it) is a fixed time offset and cannot take DST (Daylight Saving Time) into account. Use a time zone name for that (not an abbreviation). These are available in PostgreSQL:
SELECT * FROM pg_timezone_names;
For Warsaw this should be 'Europe/Warsaw'
. The system knows the bounds for DST from its stored information and applies the according time offset.
Also, your query can be simplified.
As created_at
is a timestamp [without time zone]
, the values saved reflect the local time of the server when the row was created (saved internally as UTC timestamp).
There are basically only two possibilities, depending on the time zone(s) of your client.
Your reading client runs with the same setting for timezone
as the writing client: Just cast to date.
SELECT *
FROM articles
WHERE created_at::date = '2012-08-19';
Your reading client runs with a different setting for timezone
than the writing client: Add AT TIME ZONE '<tz name of *writing* client here>
'. For instance, if that was Europe/Warsaw
, it would look like:
...
WHERE (created_at AT TIME ZONE 'Europe/Warsaw')::date = '2012-08-19';
The double application of AT TIME ZONE
like you have it in your posted answer should not be necessary.
Note the time zone name instead of the abbreviation. See:
If you span multiple time zones with your application ..
.. set the column default of created_at
to now() AT TIME ZONE 'UTC'
- or some other time zone, the point being: use the same everywhere.
.. or, preferably, switch to timestamptz
(timestamp with time zone
).