I have a table called items. It contains a column tz with timezone identifiers (like America/New_York, Europe/London, etc).
I want to select all the items where the current time is 8AM +/- 5 minutes.
So if I run the query at 8AM EST it will return rows where tz = 'America/New_York'.
If I run the query at 9AM EST it will return rows where tz = 'America/Chicago'.
SELECT *
FROM items
WHERE CAST(current_timestamp at time zone tz AS time) BETWEEN '07:55' AND '08:05'
You should be storing the offset for each timezone. Then the query is as simple as
select * from items where GETDATE() between
DATEADD(minute,5,DATEADD(HOUR,offset,GETUTCDATE())) and
DATEADD(minute,-5,DATEADD(HOUR,offset,GETUTCDATE()))
I'm using SqlServer GETUTCDATE and DATEADD functions, but you can easily make them work in postgresql if you lookup the correct function names.
EDIT
If you can't add a offset to the table, create a timezone table with the string timezone and numeric offset. Join and run the above query.
Your tz field is valid if it respects this: http://www.postgresql.org/docs/8.0/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
If so, I think this should work (no tested):
SELECT *
FROM items
WHERE LOCALTIMESTAMP BETWEEN
(LOCALTIMESTAMP AT TIME ZONE tz) - interval '5 minutes' AND
(LOCALTIMESTAMP AT TIME ZONE tz) + interval '5 minutes'
Related
Usually we use EXTRACT (FROM YEAR date_column) = 2000 (let it be 2000 year). Also we can add EXTRACT (MONTH FROM date_column) = 1 (let it be January). Also we can extract a day - EXTRACT (DAY FROM date_column) = 5 (let it 5). But is it possible to use the pattern for this data? How does it look like in Postgres SQL
Say we have the table Shipment, the columns - date_payment, quantity, sum.
I'd like to get the table that content all shipments for 01.01.2020
How to query this table with data format 'YYYY-MM-DD', not using EXTRACT-function?
If the date column is a date type then:
SELECT * FROM some_table WHERE date_col = '2020-01-01';
If the column is timestamp or timestamptz then:
SELECT * FROM some_table WHERE date_trunc('day', date_col) = '2020-01-01'
Beware that with timestamptz time zones come into play when doing the date_trunc. From here date_trunc:
When the input value is of type timestamp with time zone, the truncation is performed with respect to a particular time zone; for example, truncation to day produces a value that is midnight in that zone. By default, truncation is done with respect to the current TimeZone setting, but the optional time_zone argument can be provided to specify a different time zone. The time zone name can be specified in any of the ways described in Section 8.5.3.
For a timestamp value per the above link:
A time zone cannot be specified when processing timestamp without time zone or interval inputs. These are always taken at face value.
I'm querying the database (RedShift) and I have a piece of information stored in epoch MS format. Envision a table along the lines of:
Purchase, date
1, 1620140227019
2, 1620140227045
3, 1620140226573
I need to convert the timestamp to a readable date but I can't make it work with to_timestamp() or extract(). The problem is first with the size of the value (13 digits are not supported).
The closest solution I have is
select to_timestamp(1620140226573/1000, 'SS')
But the result is 0051-05-04 14:57:06. In other words month, date and seconds are correct but the year is wrong.
You can run this query
select to_timestamp(round(1620140227254/1000))
The solution was in the documentation: https://docs.aws.amazon.com/redshift/latest/dg/r_Dateparts_for_datetime_functions.html
SELECT timestamp with time zone 'epoch' + 1620140227019/1000 * interval '1 second' AS converted_timestamp
or
select '1970-01-01'::date + 1620140227019/1000 * interval '1 second'
I have Oracle 12c DB table and one of it's column utc_timestamp is of type
UTC_TIMESTAMP TIMESTAMP(6) WITH TIME ZONE
It stores timestamp in UTC while current_timestamp and systimestamp both gives timestamp in different timezones.
How can I get time difference in MAX(utc_timestamp) and current_timestamp in minutes ignoring time difference due to different time zones.
For example:
select current_timestamp from dual;
Gives=> 23-AUG-17 04.43.16.253931000 PM AMERICA/CHICAGO
select systimestamp from dual;
Gives=> 23-AUG-17 05.43.16.253925000 PM -04:00
select max(UTC_TIMESTAMP) from table_name;
Gives=> 23-AUG-17 09.40.02.000000000 PM +00:00
For above condition when I run SQL to check time difference between in MAX(utc_timestamp) and current_timestamp I should get number 3.
I think I need something like:
select (extract(minute from current_timestamp) - extract(minute from max(UTC_TIMESTAMP)) * 1440) AS minutesBetween from table_name;
But different timezones are messing it up and I get negative number like -4317. This might be correct as current_timestamp will be higher than max(utc_timestamp) being in CST. So I tried:
select (extract(minute from CAST(current_timestamp as TIMESTAMP(6) WITH TIME ZONE)) - extract(minute from max(UTC_TIMESTAMP)) * 1440) AS minutesBetween from table_name;
This SQL runs without error but producing a big negative number like -83461. Please help me find what am I doing wrong.
You really have two problems here.
One is to convert CURRENT_TIMESTAMP to UTC. That is trivial:
select CURRENT_TIMESTAMP AT TIME ZONE 'UTC' from dual [.....]
(use the AT TIME ZONE clause https://docs.oracle.com/cd/B19306_01/server.102/b14225/ch4datetime.htm#i1007699)
The other is that the difference between two timestamps is an interval, not a number.
select current_timestamp at time zone 'UTC'
- to_timestamp_tz('24-AUG-17 04.00.00.000 AM UTC', 'dd-MON-yy hh.mi.ss.ff AM TZR')
from dual;
produces something like
+00 00:02:39.366000
which means + (positive difference) 00 days, 00 hours, 02 minutes, 39.366 seconds.
If you just want the minutes (always rounded down), you may wrap this whole expression within extract( minute from < ...... > ). Be aware though that the answer will still be 2 (minutes) even if the difference is five hours and two minutes. It is probably best to leave the result in interval data type, unless you are 100% sure (or more) that the result is always less than 1 hour.
I have a table in which every row represents a user. I am also storing the user's time zone as text such as 'America/Denver', 'America/New_York' etc.
Is it possible to write a query that would return users for whom their current time of day is between 1 PM to 11 PM respective to their time zone?
Given this table:
CREATE TABLE usr (
usr_id serial PRIMARY KEY
, usr text NOT NULL
, tz text -- time zone names
);
Use the AT TIME ZONE construct:
SELECT *, (now() AT TIME ZONE tz)::time AS local_time
FROM usr
WHERE (now() AT TIME ZONE tz)::time BETWEEN '13:00'::time AND '23:00'::time;
Including upper and lower bounds 1 PM and 11 PM.
SQL Fiddle.
Details for AT TIME ZONE:
Ignoring timezones altogether in Rails and PostgreSQL
SELECT CONVERT_TZ(FROM_UNIXTIME(1196440219),'GMT','America/Denver');
SELECT * FROM table WHERE
DATE_FORMAT(CONVERT_TZ(FROM_UNIXTIME(timestamp_column),'GMT','America/Denver'),'%H') between 13 and 23
I'm working with a legacy postgres db that uses column definitions as follows:
timestamp without time zone default (CURRENT_TIMESTAMP
AT TIME ZONE 'UTC')
and
timestamp without time zone default (CURRENT_TIMESTAMP
AT TIME ZONE 'UTC' + 30 * interval '1 day')
Unfortunately these cannot be changed.
The goal of the latter one is that the default value is 30 days in the future.
I'm trying to add a modern day junit test framework using hsqldb on top of it.
To bring this in line with hsqldb, the first definition needed to be changed to:
timestamp without time zone default CURRENT_TIMESTAMP
AT TIME ZONE INTERVAL '0:00' HOUR TO MINUTE
However, try as I may, I cannot figure out a way to replicate the column with the addition of the 30 days
You can use a TRIGGER for this kind of default value:
CREATE TRIGGER t BEFORE INSERT ON the_table
REFERENCING NEW AS newrow FOR EACH ROW
BEGIN ATOMIC
SET newrow.the_column = CURRENT_TIMESTAMP AT TIME ZONE INTERVAL '0:00' HOUR TO MINUTE + INTERVAL '30' DAY;
END
Update: PostgreSQL compatibility has been extended to accept values in the future. Example
timestamp without time zone default (CURRENT_TIMESTAMP AT TIME ZONE INTERVAL '0:00' HOUR TO MINUTE + INTERVAL 30 DAY))