I'm using PostgreSQL 8.4
. I have a column of the table my_tbl
which contains dates (timestamp without timezone
). For instance:
date
-------------------
2014-05-27 12:03:20
2014-10-30 01:20:03
2013-10-19 16:34:34
2013-07-10 15:24:26
2013-06-24 18:15:06
2012-07-14 07:09:14
2012-05-13 04:46:18
2013-01-04 21:31:10
2013-03-26 10:17:02
How to write an SQL query which returns all dates in the format:
xxxx-xx-xx 23:59:59
That's every date will be set to the end of the day.
Use the setUTCHours() method to get the start and end of the day, e.g. startOfDay. setUTCHours(0, 0, 0, 0) . The method takes the hours, minutes, seconds and milliseconds as parameters and sets them for the specified date according to universal time. Copied!
var date = new Date(); var firstDay = new Date(date. getFullYear(), date. getMonth(), 1); var lastDay = new Date(date. getFullYear(), date.
Many ways.
Using the column name "ts" in my examples. "date" for a timestamp
column would be misleading.
Cast to date
. (Here we need the type date
. In other expressions, date_trunc()
is just as well.). Then add 1
(integer
) before subtracting the interval 1 second
:
SELECT ts::date + 1 - interval '1 sec' AS last_sec_of_day
Add a single interval '1 day - 1 sec'
. No need for two operations, Postgres interval input allows a single expression.
SELECT ts::date + interval '1 day - 1 sec' AS last_sec_of_day
Simpler yet, add the desired time component to the date:
SELECT ts::date + time '23:59:59' AS last_sec_of_day
However, is not the "end of the day". The Postgres xxxx-xx-xx 23:59:59
timestamp
data type (currently, but unlikely to change) stores values with microsecond resolution.
The latest possible timestamp for a day is xxxx-xx-xx 23:59:59.999999
:
SELECT ts::date + interval '1 day - 1 microsecond' AS last_ts_of_day
Equivalent:
SELECT ts::date + time '23:59:59.999999' AS last_ts_of_day -- or interval
This last expression should be fastest besides being correct.
However, the superior approach typically is to operate with the start of the next day as exclusive upper bound, which does not depend on implementation details and is even simpler to generate:
SELECT ts::date + 1 AS next_day
The actual first timestamp of the next day:
SELECT date_trunc('day', ts) + interval '1 day' AS next_day_1st_ts
All work in any version since at least Postgres 8.4. Demo in Postgres 13:
db<>fiddle here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With