Converting GMT to CST in postgresql - postgresql

I am currently working with raw data that have timestamps in GMT and I want to convert them to CST. I am trying to use the cast function to change the timestamp, but it is not working- the times are not affected. Most of what I have read about timezones in postgresql assumes that the default timezone is UTC so I'm not sure if there is a different syntax needed for when the data I'm trying to convert is GMT. Any help is greatly appreciated!
WITH RECURSIVE "child" AS (
SELECT "ConsultantDisplayID",
"JoinDate",
"ParentPersonDisplayID"
FROM "public"."flight_export_consultant"
WHERE "ConsultantDisplayID" = '4019'
UNION
SELECT c."ConsultantDisplayID",
CAST(c."JoinDate" at time zone 'america/chicago' as timestamp) as "JoinDate"
c."ParentPersonDisplayID"
FROM "public"."flight_export_consultant" AS c
JOIN "child" AS cd
ON c."ParentPersonDisplayID" = cd."ConsultantDisplayID"),
"sponsor" AS (
SELECT
"child".*,
c1."ConsultantDisplayID",
Cast(c."JoinDate" at time zone 'america/chicago' as timestamp) as "Sponsor JoinDate"
FROM "public"."flight_export_consultant" AS c1
LEFT JOIN "child"
ON c1."ConsultantDisplayID" = "child"."ParentPersonDisplayID")
SELECT * FROM "sponsor"

As #Mike Organek pointed out a field of type timestamp assumes local time on entry. So first thing you need to establish is where the dates are being entered from and whether they are are actually being entered as GMT. For the moment assuming they are you could do the following:
select 'September 24, 2018, 4:01PM'::timestamp at time zone 'utc' at time zone 'america/chicago';
timezone
---------------------
09/24/2018 11:01:00
-- Or if you want to stick to GMT
select 'September 24, 2018, 4:01PM'::timestamp at time zone 'gmt' at time zone 'america/chicago';
timezone
---------------------
09/24/2018 11:01:00
Basically you are 'anchoring' the timestamp at UTC/GMT and then converting to 'america/chicago'. In other words replicating what a timestamptz field does.

Given that JoinDate is type timestamp, this should be a good workaround for your situation now that we have established that the values in JoinDate of type timestamp represent UTC/GMT timestamps, and your server is not in UTC/GMT. The ideal solution is to use timestamptz columns.
The trick here is to cast JoinDate to text, append a z to it to make it UTC, and then cast it to timestamptz. Once that is done, you can use at time zone 'us/chicago' to do the conversion for you.
WITH RECURSIVE "child" AS (
SELECT "ConsultantDisplayID",
"JoinDate",
"ParentPersonDisplayID"
FROM "public"."flight_export_consultant"
WHERE "ConsultantDisplayID" = '4019'
UNION
SELECT c."ConsultantDisplayID",
"JoinDate",
c."ParentPersonDisplayID"
FROM "public"."flight_export_consultant" AS c
JOIN "child" AS cd
ON c."ParentPersonDisplayID" = cd."ConsultantDisplayID"),
"sponsor" AS (
SELECT
"child".*,
c1."ConsultantDisplayID",
c."JoinDate" as "Sponsor JoinDate"
FROM "public"."flight_export_consultant" AS c1
LEFT JOIN "child"
ON c1."ConsultantDisplayID" = "child"."ParentPersonDisplayID")
SELECT "ConsultantDisplayID",
("JoinDate"::text||'z')::timestamptz at 'america/chicago' as "JoinDate",
"ParentPersonDisplayID",
"ConsultantDisplayID",
("JoinDate"::text||'z')::timestamptz at 'america/chicago' as "Sponsor JoinDate"
FROM "sponsor";

Related

Observations of the same date between hours with timestamp variable at PostgreSQL

I´m trying to run a select to chose some data between hours from the same date. The code below shows the idea, but it isn´t work. My datahora variable is a timestamp in the following format: 'yyyy-mm-dd hh24:mi:ss", as 2023-02-13 15:30:30. How can I run that?
select tr.tick, tr.cot, tr2.cot, tr2.cot-tr.cot as dif
from tb_registros tr
join tb_registros tr2 on to_char(tr.datahora, 'yyyy-mm-dd') = to_char(tr2.datahora, 'yyyy-mm-dd') and to_char(tr.datahora, 'hh24:mi:ss') between '08:55:00' and '08:56:10' and to_char(tr2.datahora, 'hh24:mi:ss') between '09:10:00' and '09:11:10'
where tick = 'ANY'
It's better to operate on proper date/timestamp or time values rather than strings. Assuming the column datahora is really defined as timestamp casting it to a date will remove the time part and casting it to a time value will remove the "day":
select tr.tick, tr.cot, tr2.cot, tr2.cot-tr.cot as dif
from tb_registros tr
join tb_registros tr2
on tr.datahora::date = tr2.datahora::date
and tr.datahora::time between '08:55:00' and '08:56:10'
and tr2.datahora::time between '09:10:00' and '09:11:10'
where tick = 'ANY'
::date is Postgres' proprietary cast operator. If you prefer ANSI SQL, you can use cast(... as date) instead

how can i get the all data from postgresql thats from the current day, between the hours of 00:00:00 and 11:59:59?

very new to the backend as well as all things postgresql, at the moment all ive been able to do is
SELECT * FROM nutrition WHERE timestamp >= (extract(epoch from now())::bigint * 1000) - 86400000 AND timestamp <= (extract(epoch from now())::bigint * 1000) + 86400000
in the frontend using js, im using Date.now() to store the timestamp in the DB.
timestamp is a column in my db thats logging the unix time in bigint format in which the food was logged. I want to get all the data from the current day from the hours beteen 12 AM midnight, and 11:59 PM. thanks.
for example, the last item i logged was last night at 10pm (1663995295337 UNIX time) so the data shouldnt include it.
show timezone returns;
America/Los_Angeles
Solution below --------------------------------------------------------------------
const today = new Date();
const beginningOfDay = today.setUTCHours(7, 0, 0, 0);
const endOfDay = today.setUTCHours(30, 59, 59, 99);
switch (method) {
case "GET":
try {
const text = `
select
*
from
nutrition
where
timestamp
between ${beginningOfDay} and ${endOfDay}`
this was the solution i was looking for, thanks for the help. sorry if i wasnt descriptive enough.
Assuming that by Unix time you mean epoch.
select extract(epoch from now());
extract
-------------------
1664038032.392004
select to_timestamp(1664038032.392004);
to_timestamp
--------------------------------
09/24/2022 09:47:12.392004 PDT
select
*
from
some_table
where
to_timestamp(1664038032.392004)
between
current_date + '00:00:00'::time AND current_date + '23:59:59'::time
UPDATE
Using timestamptz field in Postgres and an ISO datetime string from Javascript in order to properly deal with time zone.
create table tsz_test(id integer, tsz_fld timestamptz);
--In Web frontend today = new Date().toISOString(); "2022-09-24T20:57:05.830Z"
insert into
tsz_test
values (1, '2022-09-24T20:57:05.830Z'), (2, '2022-09-25T08:57:05.830Z');
select * from tsz_test ;
id | tsz_fld
----+----------------------------
1 | 09/24/2022 13:57:05.83 PDT
2 | 09/25/2022 01:57:05.83 PDT
--Borrowing from #a_horse_with_no_name answer
select * from tsz_test where tsz_fld::date = '09/24/2022'::date;
id | tsz_fld
----+----------------------------
1 | 09/24/2022 13:57:05.83 PDT
You can convert your "unix timestamp" to a date, then compare it with "today":
where to_timestamp("timestamp")::date = current_date
This assumes that your column named "timestamp" is not really a timestamp
If the column doesn't actually store seconds (which would be a unix epoch), but milliseconds you need to_timestamp("timestamp"/1000)::date instead (another source of problems that wouldn't exist if you had used a proper timestamptz or at least timestamp data type).

How to query between 2 specific hours of the day

Need to query only results from a table where a specific time is only between 10:00am EST and 09:59pm EST.
Using this query example:
SELECT
s.id as "ID",
to_char(s.started_at AT TIME zone 'UTC-5', 'HH12:MIam') as "Start_time",
FROM
stats s
WHERE
s.started_at IS NOT NULL
Does anyone have a WHERE statement that would show those results regardless of DATE?
Cast the column to time:
SELECT ...
FROM states s
WHERE CAST ((s.started_at AT TIME ZONE 'EST') AS time)
BETWEEN TIME '10:00' AND TIME '21:59';

How can I have timestamp displayed in UTC+02 (same timezone) for both the queries below?

My first query is:
SELECT distinct wfc_request_job_id,wfc_request_job_info,
replace(iso_cc,';',' ') as "iso_cc",to_char(wfc_request_start_ts,'yyyy-MM-dd HH:mm:ss') as ts,
sent_message_count,
(link_object_count + poi_object_count + point_address_object_count) as request_object_count
FROM wfc_request_job
where
wfc_request_job_id=173526;
This returns ts as 2015-08-16 03:08:59
Second Query:
SELECT wfc_request_job_id,wfc_request_start_ts,wfc_request_end_ts,replace(iso_cc,';',' ') as "iso_ccs",sent_message_count,wfc_queue_name
FROM wfc_request_job
where
to_char(wfc_request_start_ts,'YYYY-MM-DD') >= to_char(to_date('08/16/2015','MM/DD/YYYY'),'YYYY-MM-DD')
and to_char(wfc_request_start_ts,'YYYY-MM-DD') <= to_char(to_date('08/16/2015','MM/DD/YYYY'),'YYYY-MM-DD')
order by wfc_request_job_id desc
This returns ts of the job id mentioned above as - "2015-08-16 15:58:59.809+02"
How can I make both the queries return ts in UTC+02 - i.e. same timezone
The data type of wfc_request_start_ts is - timestamp with timezone
I changed to queries to have the format HH24:MI:SS however that did not help. Please note that the webapp using these queries will be opened in both Germany and USA.
According to postgresql manual to_char there is TZ (and OF as of v9.4) template patterns for Date/Time formatting.
Therefore in query you need to add it so
postgres=# select to_char(now(),'yyyy-MM-dd HH24:mm:ss TZ');
to_char
------------------------
2015-08-19 12:08:56 CEST
(1 row)
Also, make sure you specify timezone when converting
so instead
to_date('08/16/2015','MM/DD/YYYY')
use
TIMESTAMP WITH TIME ZONE '2015-08-16 00:00:00+02';
in second query.

to_char returning wrong date postgresql

So in my database i have a table with startimestamp that is "Timestamp with time zone" type
but what i want to display the timestamp without the time zone so i thought this would work
Select to_char("StartTimestamp",'YYYY/MM/DD HH24:MM:SS')from "Samples" where "ID" = 20
and a i get
"2013/08/02 14:08:04"
but the when i do it without the to_char and just call the timestamp for the same id like this
select "StartTimestamp" from "Samples" where "ID"=20
i get this which is the correct one
"2013-08-02 14:31:04-07"
I'm i missing something the to_char statement? Thanks
Change MM to MI in the minutes place
select
to_char(now(),'YYYY/MM/DD HH24:MM:SS'),
to_char(now(),'YYYY/MM/DD HH24:MI:SS');
to_char | to_char
---------------------+---------------------
2013/08/21 15:08:00 | 2013/08/21 15:51:00