how to get EST and UTC irrespective of Day - sql

I have to show EST/EDT and GMT/UTC using Oracle 10g.The issue is on Nov 2nd UTC difference will change '+ 05' hour which will cause my jobs to fail.Please let me know how to fix it without manually changing interval to 5 hours.I have tried new_time function but that does not solve the problem. The all columns are DATE datatype.
SELECT PROCESS_NAME,
date_modified as EST_DATE_MODIFIED,
date_modified + interval '+ 04' hour as GMT_DATE_MODIFIED
FROM tbl_process_status ;
Result
EST_DATE_MODIFIED GMT_DATE_MODIFIED
22-OCT-14 11:08:25 22-OCT-14 03:08:25
Thanks Ed but above query is not returning correct UTC time.
EST - 22-OCT-14 12:19:55
Correct UTC- 22-OCT-14 04:19:55
Above Query UTC 22-OCT-14 08:19:55
select (TO_NUMBER(TO_CHAR(CURRENT_TIMESTAMP, 'TZH')) * INTERVAL '1' HOUR) from dual;
-0 4:0:0.0
Thanks Multisync.
I got below result but I need data only in DD-MON-YY HH:MM:SS Format.
Expected 22-OCT-14 12:19:55
Expected 22-OCT-14 04:19:55
Result 22-OCT-14 12.19.55.000000000 PM AMERICA/NEW_YORK
Result 22-OCT-14 04.19.55.000000000 PM UTC

select systimestamp at time zone 'est' for_timestamp,
cast(sysdate as timestamp) at time zone 'est' for_date,
cast(sysdate as timestamp) at time zone 'gmt' gmt_timezone
from dual;
So you can try this (edited according to the comments)
SELECT PROCESS_NAME,
cast(cast(date_modified as timestamp) at time zone 'America/New_York' as date) as EST_DATE_MODIFIED,
cast(cast(date_modified as timestamp) at time zone 'UTC' as date) as GMT_DATE_MODIFIED
FROM tbl_process_status;

Related

Oracle SQL sysdate with time

I am using Oracle SQL. I'm trying to use sysdate with time to give the me query result. I have placed a time in the where clause, but I need it to be automatic and using the sysdate and converting to local time is the correct way. Any thoughts?
SELECT RESOURCE, AVG(SALES) AS SALES
FROM Z_HOURLY_RESOURCE
WHERE DATE_TIME_START BETWEEN to_date(to_char(FROM_TZ( CAST( (to_date('2018-08-02T05:00:00','yyyy-MM-dd"T"HH24:mi:ss') )AS TIMESTAMP ), 'America/Los_Angeles') AT TIME ZONE 'UTC', 'yyyy-MM-dd"T"HH24:mi:ss'),'yyyy-MM-dd"T"HH24:mi:ss')
AND to_date(to_char(FROM_TZ( CAST( (to_date('2018-08-02T13:00:00','yyyy-MM-dd"T"HH24:mi:ss')+1) AS TIMESTAMP ), 'America/Los_Angeles') AT TIME ZONE 'UTC', 'yyyy-MM-dd"T"HH24:mi:ss'),'yyyy-MM-dd"T"HH24:mi:ss')
It's slightly hard to work out quite what you need without sample data, but it sounds like you want to convert the time range 05:00 to 13:00 in your local session time zone (e.g. LA) to UTC to compare with the UTC-based timestamps in your table.
You can do that with:
WHERE DATE_TIME_START >= sys_extract_utc(cast(trunc(current_date) + 5/24 as timestamp with time zone))
AND DATE_TIME_START < sys_extract_utc(cast(trunc(current_date) + 13/24 as timestamp with time zone))
I've used >= and < rather than between on the assumption you really want up to 13:00, which is usually the case for time ranges. If you do want to include data form exactly 13:00:00 then change that < to <=, or go back to between.
TO explain what that is doing a but: current_date gives you the date/time in your session time zone. Truncating that sets the time to midnight (by default), so you can then add either 5 or 13 hours to get the times you want. That is still a date, so you can cast to timestamp with time zone so it represents that time in your session time zone again. You can then use sys_extract_utc() to get the UTC-equivalent timestamp.
To demonstrate those steps:
alter session set time_zone = 'America/Los_Angeles';
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS.FF1';
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF1 TZH:TZM';
select sysdate as a,
current_date as b,
trunc(current_date) as c,
trunc(current_date) + 5/24 as d,
cast(trunc(current_date) + 5/24 as timestamp with time zone) as e,
sys_extract_utc(cast(trunc(current_date) + 5/24 as timestamp with time zone)) as f
from dual
union all
select sysdate as a,
current_date as b,
trunc(current_date) as c,
trunc(current_date) + 13/24 as d,
cast(trunc(current_date) + 13/24 as timestamp with time zone) as e,
sys_extract_utc(cast(trunc(current_date) + 13/24 as timestamp with time zone)) as f
from dual;
A B C D E F
------------------- ------------------- ------------------- ------------------- ---------------------------- ---------------------
2018-08-02 18:56:23 2018-08-02 10:56:23 2018-08-02 00:00:00 2018-08-02 05:00:00 2018-08-02 05:00:00.0 -07:00 2018-08-02 12:00:00.0
2018-08-02 18:56:23 2018-08-02 10:56:23 2018-08-02 00:00:00 2018-08-02 13:00:00 2018-08-02 13:00:00.0 -07:00 2018-08-02 20:00:00.0
First of all you don't have to cast a TIMESTAMP to a CHAR and then back again to a TIMESTAMP.
Assuming DATE_TIME_START is a TIMESTAMP and times are given in UTC you can make it simpler. When Oracle compares TIMESTAMP WITH TIME ZONE values then comparison are always done automatically at UTC time value. Your condition would be like this.
SELECT RESOURCE, AVG(SALES) AS SALES
FROM Z_HOURLY_RESOURCE
WHERE FROM_TZ(DATE_TIME_START, 'UTC')
BETWEEN TO_TIMESTAMP_TZ('2018-08-02T05:00:00 America/Los_Angeles', 'yyyy-MM-dd"T"HH24:mi:ss TZR')
AND TO_TIMESTAMP_TZ('2018-08-02T13:00:00 America/Los_Angeles', 'yyyy-MM-dd"T"HH24:mi:ss TZR')
However, due to function FROM_TZ(DATE_TIME_START, 'UTC') the performance might not be the best, it depends on your data.
If you need condition based on current time it would be like this:
SELECT RESOURCE, AVG(SALES) AS SALES
FROM Z_HOURLY_RESOURCE
WHERE FROM_TZ(DATE_TIME_START, 'UTC')
BETWEEN TRUNC(SYSTIMESTAMP)
AND TRUNC(SYSTIMESTAMP) + INTERVAL '1' DAY
Above query just illustrate time zone handling. You don't have to consider time zone of SYSTIMESTAMP, comparison will work in any case.

Accounting for timezone in postgres query

In am trying to automatically account for timezone in my postgres query. My goal is to select records that are between 0:00 and 23:59 in EST or UTC - 5:00.
The current query only returns records between 0:00 and 23:59 in UTC time.
select path, start_time from routes where routes.network_id = 1 and routes.start_time between '2017-06-13 00:00:00'::timestamp AND '2017-06-13 23:59:59'::timestamp
the column start_time is a timestamp without timezone, so by default it is in UTC
SELECT pg_typeof("start_time") from routes limit 1;
returns timestamp without timezone
how would one write a query to account for 5 hours difference and convert start_time to UTC - 5?
Try this:
select path, start_time - interval '5 hours' as start_time_est
from routes
where routes.network_id = 1
and routes.start_time between '2017-06-13 00:00:00-5'::timestamp with time zone
AND '2017-06-13 23:59:59-5'::timestamp with time zone;

Get today's date - Different timezone

I just wanted to know whether the following SQL is good to convert US server time to Thailand date. As we have 12 hours difference in the time, and TH time is ahead of U.S time
SELECT TO_DATE(
TO_CHAR(
SYSTIMESTAMP AT TIME ZONE 'Asia/Bangkok', 'yyyy-mm-dd',
'NLS_DATE_LANGUAGE = american'), 'yyyy-mm-dd') AS TODAY
FROM dual;
It works perfectly fine. But are there any other better way to convert timestamp of server from one timezone to another as I need to compare today's date based on this result in my outer SQL.
You could CAST the timestamp to your desired timezone.
For example,
SQL> WITH data AS (
2 SELECT SYSTIMESTAMP AT TIME ZONE 'Asia/Bangkok' tm_bangkok FROM dual
3 )
4 SELECT tm_bangkok,
5 CAST(tm_bangkok AT TIME ZONE 'EST' AS TIMESTAMP) tm_est
6 FROM data;
TM_BANGKOK TM_EST
--------------------------------------------- ----------------------------
03-NOV-15 12.54.18.951000 PM ASIA/BANGKOK 03-NOV-15 12.54.18.951000 AM
There is no reason to cast a TIMESTAMP to CHAR and then back to TIMESTAMP again. Simply do
SELECT SYSTIMESTAMP AT TIME ZONE 'Asia/Bangkok' AS TODAY
FROM dual;

Converting NUMBER to DATE

I have a numeric field in my Oracle database that represents the date.
I'm not so familiar with Oracle commands.
I was wondering if anyone could provide some guide here.
Thanks.
example: 1435755908 = 7/1/2015 9:05
This is a Unix Timestamp, i.e. the seconds since January 1970, try this formula:
timestamp '1970-01-01 00:00:00' + 1435755908/86400
Since there seems to be a time zone difference:
select date '1970-01-01' + 1435755908/86400 as converted from dual;
CONVERTED
----------------------------------------
2015-07-01 13:05:08
you seem to need to do some time zone manipulation. Epoch times are UTC so you can use from_tz to declare that, and then at time zone to get the US/East Coast equivalent:
select from_tz(cast(date '1970-01-01' + 1435755908/86400 as timestamp), 'UTC')
at time zone 'America/New_York' as converted from dual;
CONVERTED
----------------------------------------
2015-07-01 09:05:08.000 AMERICA/NEW_YORK
Which is a time stamp with time zone. If you want it as a plain date then cast it:
select cast(from_tz(cast(date '1970-01-01' + 1435755908/86400 as timestamp), 'UTC')
at time zone 'America/New_York' as date) as converted from dual;
CONVERTED
----------------------------------------
2015-07-01 09:05:08

new_time returning time in 12hrs format

In my function I want to convert time from GMT to BST.
My query is like below
SELECT TO_CHAR(NEW_TIME ((TRUNC(SYSDATE) + 20/24 + 21/1440),
'GMT',
'BST'),
'HH24:MI'
)
FROM DUAL;
Its returning me '9:21' instead of '21:21'.
Please help! Thank you!
From the documentation, BST refers to Bering Standard Time, and not British Summer Time as you are expecting.
Bering Standard Time is at UTC-11, so the result that you get is as expected.
NEW_TIME function can accept only limited timezones specified in the above documentation.If you want to convert GMT to British Summer Time,
you should probably use 'Europe/London' timezone.
select (cast(your_date as timestamp) at time zone 'GMT') at time zone 'Europe/London'
from dual;
So your query will be,
SQL> select
(cast((TRUNC(SYSDATE) + 20/24 + 21/1440) as timestamp) at time zone 'GMT') at time zone 'Europe/London',
to_char((cast((TRUNC(SYSDATE) + 20/24 + 21/1440) as timestamp) at time zone 'GMT') at time zone 'Europe/London','hh24:mi')
from dual;
(CAST((TRUNC(SYSDATE)+20/24+21/1440)ASTIMESTAMP)ATTIMEZONE'GMT')ATTIMEZONE' TO_CH
--------------------------------------------------------------------------- -----
14-MAY-14 09.21.00.000000 PM EUROPE/LONDON 21:21