Psql wrong date from timestamp - psql

cloud somebody explain to me why casting timestamp to date in psql gives me wrong value? I have in my db stored time stamp value 2016-12-04 00:05:09.748000 and my machine time is in UTC, and datatype in psql is TIMESTAMP WITH TIME ZONE. If I did this,
orders.completed::date
it gives me 2016-12-03. Problem is that if i have some orders around midnight aggregate functions gives me wrong values. Is there some way how to solve it? I would appreciate any help!

Try this :
(orders.completed::timestamp at time zone 'UTC' at time zone 'America/Los_Angeles')::date;
You need to insert your timezone in query

Hm, I can't reproduce it:
b=# set timezone to "GMT+10";
SET
b=# create table edge (t timestamptz);
CREATE TABLE
b=# insert into edge select now();
INSERT 0 1
b=# select t::date, t from edge;
t | t
------------+-------------------------------
2016-12-08 | 2016-12-08 00:18:30.740132-10
(1 row)

Related

Incorrect result set of timezone field in Teradata

I am trying to fetch the result of a table with timezone datatype field in TD 14 SQL assistant.
lock row for access sel * from uk_istl_rtm_data.rtim_message_event_history
where substr(message_name,1,5) in ('G1874','G1906','G1571')
and response_dttm BETWEEN '2021-03-30 00:00:00' AND '2021-03-30 23:59:59'
This query is fetching records from 29th March 23:00 after daylight savings.
I have checked the TimeDateWZControl of DBScontrol and its 3.
I am looking for a way in which I can handle this timezone issue data at query level only.
Thanks all for the suggestion. I casted it as below and it worked.
SET TIME Zone 'europe central';
SELECT
CAST(response_dttm AS TIMESTAMP(6) FORMAT 'Y4-MM-DDBHH:MI:SSBZ') AT 'europe central'
from uk_istl_rtm_data.rtim_message_event_histor
where response_dttm BETWEEN '2021-03-30 00:00:00' AND '2021-03-30 23:59:59';

PostegreSQL Combine columns and convert to timestamp with local time zone

I'm creating a time slot table in Rails with PostegreSQL that contains columns like
slots
name | type
-----|-----
day | date
hour | int
min | int
hour would be like 11, 12, 13, 14 ...
min would be like 0, 5, 10, 15 ...
I'm trying to use these three columns and create a timestamp in order to compare against Time.now to pull records that's upcoming in the future.
Since PG's to_timestamp function creates timestamp with UTC as default timezone, I want to create time from the three columns to use server's timezone and my attempt is below.
Slot.select("
to_timestamp(
concat_ws(
' ',
day::text,
concat_ws(
':',
hour::text,
min::text),
'#{Time.now.zone}'),
'YYYY-MM-DD HH24:MI (TZ)')
AS t")
And it gives me the error:
PG::FeatureNotSupported: ERROR: "TZ"/"tz"/"OF" format patterns are not supported in to_date
Any suggestions or thoughts would be great.
Thanks
The to_timestamp() function returns a timestamp with time zone value. If you do not explicitly specify a time zone, then the time zone of the server is used. That seems to be all that you need, so you can safely forget about specifying anything beyond the simple date and time.
Seeing what you are trying to do, however, it would be much easier to use the make_time() function and add the resulting time to the day date to get the timestamp you need. This saves you lots of conversions to text and then back to a timestamp:
Slot.select("day + make_time(hour, min, 0.0::float) AS t");

Group by date from a specific time to time in Rails

I'm trying to figure out if it's possible to group data by date from a specific time of a date to a time in next date.
I've a bills table in Postgresql database with the following columns:
id serial NOT NULL,
bill_amount double precision,
tax_amount double precision,
discount double precision,
grand_total double precision,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
I want group by clause like from date 2015-09-12 06:00:00.00000 to date 2015-09-13 06:00:00.00000, means all records less than 2015-09-13 06:00:00.00000 and greater than 2015-09-12 06:00:00.00000 will be considered as data of 12th September. So if I want to get the data of a month with group by date, is it possible?
In Postgresql you could use this as your grouping expression:
date_trunc('day',created_at-interval '6h')
(assuming created_at is the field you are wanting to group by).
I am no Rails expert, but glancing through the documentation I formed the opinion you might be able to get it to issue such SQL with something like
Bills.select("date_trunc('day',created_at-interval '6h') as day")
.group("date_trunc('day',created_at-interval '6h')")
Incidentally, I am guessing the reason you want the days to run from 06:00 to 06:00 is that the timezones of the date columns are not aligned - you would be better off to either ensure that the data stored in these columns is aligned so that days run from 00:00 - 00:00, or to use timestamp with timezone as the type of these columns if the table will store data from multiple time zones.

TimeZone and DST in Rails and PostgreSQL

Background
Article model with default created_at column
Rails config.time_zone = 'Warsaw'
I've got an article with created_at = local time 2012-08-19 00:15 (2012-08-18 22:15 in UTC).
Goal
To receive all articles created in 2012-08-19 (in local time).
My (not working properly) solution
Article.where(
"date_trunc('day', created_at AT TIME ZONE '#{Time.zone.formatted_offset}')
= '#{Date.civil(2012, 8, 19)}'"
)
Which generates SQL:
SELECT "articles".* FROM "articles"
WHERE (date_trunc('day', created_at AT TIME ZONE '+01:00') = '2012-08-19')
And returns an empty set. But if I run the same query in psql it returns an article ... which confuses me.
Question
What am I doing wrong and how to fix it?
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:
Time zone names with identical properties yield different result when applied to timestamp
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).
Linked answer helped. I have to run following query:
SELECT *
FROM articles
WHERE (created_at AT TIME ZONE 'UTC' AT TIME ZONE 'CEST')::date = '2012-08-19';
This question would need the exact definition of the column created_at (what data type exactly?)
Rails always creates created_at column as timestamp without time zone. So I have to make the first AT TIME ZONE 'UTC' to say dbms that this timestamp is at UTC, and the second one to display date at CEST zone.

i need to update the current time in a sql query

Usage of Time.now or Time.now.to_s or Time.now.to_datetime is throwing error.
Usage of Date.today doesn't help as it stores the date with time as 12.00 AM and not the current time stamp.
Please help me in resolving this issue.
I'm not sure why and what is throwing an error, but if you're trying to generate a date string that is correct SQL from Ruby (specifically Rails here) you can use Time.now.to_s(:db).
I used CURRENT_TIMESTAMP to get the current date with timestamp. It worked.
thanks for your help.
Did you try a statement of the kind (with now() in the update statement):
INSERT INTO table1 (field1, field2, field3, timestampfield) VALUES ('value1', 'value2', 'value3', now())
[EDIT:] Have a look here for an explanation of "now()"
For update try something like:
UPDATE table1 SET mytime = now();
Another option for you if you want to put proper time on insert, it is just set function now() for the datetime field default.
Time.now.to_formatted_s :db this should give you db friendly time stamp.
http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Time/Conversions.html#M001093

Resources