Qt and postgresql timezone - postgresql

We have just changed timezone, and it gives me a problem with database
(I am now in the timezone GMT+2).
I have to check when something starts and I use this query :
SELECT *,extract(epoch from start at time zone 'cet') as start_, extract(epoch from stop at time zone 'cet') as stop_ from czas;
and it's wrong, because my start_/stop_ is 1 hour older : i.e that should be 16 instead of 17 and 'cet' should be replaced by 'cest'.
I found QTimeZone class, which should display current short zone name (cet/cest), but when I use it like this :
QDateTime now = QDateTime::currentDateTime();
QTimeZone zone_;
qDebug()<<"ZONE: "<<zone_.displayName(now,QTimeZone::ShortName);
I get an empty string.
Does anyone have an idea why?

I can't answer why QT isn't doing what you expect.
Perhapse I can help with solving the issue you started with which is the issue of using the correct timezone? For this PostgreSQL offers a number of timezone names which are set to the country and not the number of hours offset. For example 'Europe/London' specifies 'GMT' for winter timestamps and 'BST' for summer timestamps.
The list of these has been removed in the 9.x manual but in the 8.1 manual the list can be found here:
http://www.postgresql.org/docs/8.1/static/datetime-keywords.html
For your system use the following to get a complete list of timezone names:
select * from pg_timezone_names;
I don't know which of these is most suited to your application but for example your code could be changed to:
SELECT *,extract(epoch from start time zone 'Europe/Paris') as start_, extract(epoch from stop at time zone 'Europe/Paris') as stop_ from czas;

Related

how to add a plus sign and milliseconds to a date in postgresql?

the date is like 2021-07-23
the expected output is like this 2021-07-24 00:00:00+08 notice the +08 ?
I tried like this below, but i am not getting the plus symbol
s_table.school_date + INTERVAL '1 day'
any idea how to make that +08 appear ?
I haven't been able to test it, but have you tried casting that date to a timestampz?
See this page from postgresql tutorial on the different timestamp types.
So you could try:
(s_table.school_date + INTERVAL '1 day')::timestampz
to cast your current value to a timestamp with a timezone.
If the timezone returned is incorrect you can use SET timezone='America/Los_Angeles' or find the timezone your current db is using with SHOW timezone; You can also see all timezones for your database with SELECT * FROM pg_timezone_names;.
I got the timezone specific information from this resource.
I would be sure to test out setting the timezone in a transaction first as I'm concerned it would set the timezone for your entire database and that might affect other procedures / queries happening in your database.
I hope this helps! Sorry I couldn't try it out first before sending this information along.
edit: looks like I was a bit slow! Happy you figured it out :)
That's the time with time zone included.
Try running the following in Postgres and it will return you the datetime with time zone which is after + or - depending on where you are.
SELECT NOW();
Edit-01:
try the following code:
s_table.school_date::timestamptz + INTERVAL '1 day'

Postgres timestamp with timezone

I have column 'event_date_time' in my 'events' table with type 'timestamp with timezone'. My python flask application is saving date like '2014-08-30 02:17:02+00:00' but postgres automatically converts it to '2014-08-30 07:17:02+05'. It converts the timestamp to my local timezone i-e Pakistan. I want to save it without converting.
I have tried
set timezone='UTC'
and it does change timezone to 'UTC' but pgadmin3 is still saving the converted time.
I am using MAC OS and Postgresql 9.3.
The reason pgadmin is displaying hours +5 is because your system timezone is set to this.
When you save a "timestamp with time zone" value at GMT + or - any value, the system offsets whatever timezone your input was to GMT (or UTC), so that when you go to retrieve it, you can specify the timezone you want it displayed in.
For example let's establish a current time for say... New York.
select now()::timestamp with time zone at time zone 'America/New_York';
At the time of asking it returned '2014-08-23 08:50:57.136817'. 8:50 Saturday morning, or 8:51 if you're being pedantic.
Now if we take that same time and display it in GMT we will see a different result:
select '2014-08-23 08:50:57.136817 America/New_York'::timestamp with time zone at time zone 'GMT';
Now have a new time of '2014-08-23 12:50:57.136817'... 5 hours into the "future"!
Finally let's get the original timestamp and display it in what I believe is the Pakistan time zone (PKT) and see what it shows
select '2014-08-23 08:50:57.136817 America/New_York'::timestamp with time zone at time zone 'PKT';
The result? '2014-08-23 17:50:57.136817' further into the future still!
Again I must stress the reason it can do this is because it is always converting the input time offset to UTC or GMT. Postgres processes all of its "timestamp with time zone" data types in this way. It is designed to avoid time zone problems such as daylight savings and so on.
Your issue appears to be that python is inserting the time at an offset of +00, and if this was supposed to be a local time then you will be 5 hours off as far as postgres is concerned. Without knowing exactly what queries python is making, I would assume you may want to look at that to make sure it is giving you the correct time, presumably set timezone='PKT' should be a fix. Either way, when you are viewing timestamp with time zone using a browser such as pgadmin, the timestamp is being converted to your local timezone and this is why you see +5.
Alternatively if you do wish to see those times at +00 then you must specify that you want this in your SELECT queries.

the property timestamp on posgress

I have two data base in two differents machines with the same schemas, tables and data. I launch this query:
select mydate from mytable where date = '2013-10-03 14:25:00-07'::timestamp::date
the first machine return the correct rows and the second one doesn´t, both machines has the same prostgres version (9.2)
the only different between the machines is that first one works on windows and the second one on Linux (Centos)
Any suggestion?
'2013-10-03' can be interpreted as Oct, 3rd or March, 10th, depending on your datestyle setting. #Chris has more on that.
In addition to that, your query is generally incorrect. This expression is misleading:
'2013-10-03 14:25:00-07'::timestamp
timestamp in Postgres defaults to timestamp without time zone, which doesn't recognize time zone offsets. Therefore, the time zone offset -07 is discarded.
Use instead:
'2013-10-03 14:25:00-07'::timestamptz
Match the point in time:
SELECT * FROM mytable
WHERE mydate = '2013-10-03 14:25:00-07'::timestamptz
Does not depend on your local time zone setting, since the data type of the column is timestamp with time zone as you clarified in a later comment.
Match the day:
...
WHERE mydate::date = '2013-10-03 14:25:00-07'::timestamptz::date
Depends on your local time zone setting, which defines lower and upper borders of the "day".
Detailed explanation in this related answer:
Ignoring timezones altogether in Rails and PostgreSQL
The cleanest solution would be to, at the beginning of the session, just issue the following command:
SET datestyle = "ISO, YMD";
This will ensure properly handling the timestamp according to your input format.

Time zone with daylight savings times in PostgreSQL

We're deploying our own stream gauges (a lot like this USGS gauge: http://waterdata.usgs.gov/usa/nwis/uv?site_no=03539600) so us kayakers know whether or not there's enough water to paddle the stream and don't waste time and gas to drive out there. We hope install a few of these across the southeast whitewater region which spans the eastern and central time zones.
I'm storing the time a record is inserted using the default value of current_time for the record. I'd like to later display the data using the MM/DD/YYYY HH12:MI AM TZ format, which outputs reading like 03/12/2012 01:00 AM CDT. I'd also like for the output to be aware of changes in day light savings time, so the last part of the previous sentence would change between CST and CDT when we 'spring forward' and 'fall back'. This change occurred on 3/11/2012 this year and I've included dates on both sides of this DST line below. I'm using my Windows 7 laptop for development and we will later be deploying on a Unix box. Postgres has apparently detected that my Windows computer is set to eastern US time zone. I'm trying this with a 'timestamp without time zone' field and a 'timestamp with time zone' field but can't get it to work.
I've tried using 'at time zone' in my selects and every thing is working until it's time to display the time zone. The actual hour is part of the time stamp is correctly subtracted by an hour when I ask for the time in CDT. But EDT is displayed in the output.
SELECT reading_time as raw,
reading_time at time zone 'CDT',
to_char(reading_time at time zone 'CDT',
'MM/DD/YYYY HH12:MI AM TZ') as formatted_time
FROM readings2;
"2012-04-29 17:59:35.65";"2012-04-29 18:59:35.65-04";"04/29/2012 06:59 PM EDT"
"2012-04-29 17:59:40.19";"2012-04-29 18:59:40.19-04";"04/29/2012 06:59 PM EDT"
"2012-03-10 00:00:00";"2012-03-10 00:00:00-05";"03/10/2012 12:00 AM EST"
"2012-03-11 00:00:00";"2012-03-11 00:00:00-05";"03/11/2012 12:00 AM EST"
"2012-03-12 00:00:00";"2012-03-12 01:00:00-04";"03/12/2012 01:00 AM EDT"
I'm storing the time zone that each of our gauges is located in a character varying field a separate table. I considered just appending this value to the end of the time output, but I want it to change from from CST to CDT without my intervention.
Thanks for your help.
Instead of using time zone abbreviations like CDT or CST, you could consider using full Olson-style time zone names. In the case of central time, you could choose a time zone. Either one that matches your location, such as America/Chicago, or just US/Central. This ensures PostgreSQL uses the Olson tz database to automatically figure out whether daylight saving time applies at any given date.
You definitely want a TIMESTAMP WITH TIME ZONE column (which is also known as timestamptz in PostgreSQL). That will store the timestamp in UTC, so that it represents a particular moment in time. Contrary to what the name suggests, it does not save a time zone in the column -- you can view the retrieved timestamp in the time zone of your choosing with the AT TIME ZONE phrase.
The semantics of TIMESTAMP WITHOUT TIME ZONE are confusing and nearly useless. I strongly recommend you don't use that type at all for what you are describing.
I'm really confused by the part of the question which talks about storing the timestamp in a CHARACTER VARYING column. That seems as though it might be part of the problem. If you can store it in timestamptz right from the start I suspect that you will have fewer problems. Barring that, it would be safest to use the -04 notation for offset from UTC; but that seems like more work to me for no benefit.
You can create a table of known timezones in the format suggested in Guan Yang's answer, and then use a foreign key column to this table. Valid timezones can be obtained from pg_timezone_names I've gone into more detail in this related answer.

Local time zone offset in PostgreSQL

My web app stores all timestamps in UTC without time zones. I have a shell/psql script that returns a list of recent logins, and I want that script to display login times in the server's local time zone (which may vary depending on where the server is and with daylight savings).
To get an interval representing the difference between my database server's time zone and UTC, I'm currently using this hack:
SELECT age(now() at time zone 'UTC', now());
That works, but is there a more straightforward way?
There's a server configuration parameter called "timezone" that returns a valid timezone string, but I don't think it's possible to access those parameters in a query. (I guess that's a separate question, but an answer to it would resolve the time zone issue.)
SELECT current_setting('TIMEZONE')
This can be used in a query, however, this does not give a numerical difference.
Your solution is fine.
To get # of seconds difference as an integer, I have used simply:
select extract( timezone from now() );
Get the interval based on shaunc's answer:
select (extract(timezone from now()) || 'seconds')::interval;