sysdate と時刻を EST などの特定のタイムゾーンに変換する必要があります。現在のタイムゾーンを推測できません。
これをplsqlで変換する方法は?私を助けてください。
sysdate と時刻を EST などの特定のタイムゾーンに変換する必要があります。現在のタイムゾーンを推測できません。
これをplsqlで変換する方法は?私を助けてください。
TIMESTAMP WITH TIME ZONE
( など)があると仮定すると、構文systimestamp
を使用できます。AT TIME ZONE
たとえば、systimestamp
異なるタイム ゾーン名を指定することで、現在のタイム ゾーンを UTC (GMT)、東部、および太平洋のタイム ゾーンに変換できます。
SQL> ed
Wrote file afiedt.buf
1 select systimestamp at time zone 'UTC' current_time_in_utc,
2 systimestamp at time zone 'Us/Eastern' current_time_in_est,
3 systimestamp at time zone 'US/Pacific' current_time_in_pst
4* from dual
SQL> /
CURRENT_TIME_IN_UTC
---------------------------------------------------------------------------
CURRENT_TIME_IN_EST
---------------------------------------------------------------------------
CURRENT_TIME_IN_PST
---------------------------------------------------------------------------
26-APR-12 05.36.11.802000 PM UTC
26-APR-12 01.36.11.802000 PM US/EASTERN
26-APR-12 10.36.11.802000 AM US/PACIFIC
これはどう?
select to_timestamp_tz(to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') || ' ' || 'FROM_TIME_ZONE', 'YYYY-MM-DD HH24:MI:SS TZR') at time zone 'TO_TIME_ZONE'
from dual;
以下は、夏時間を考慮しない現在の EST 時間 ( UTC - 5 時間) を示します。
SELECT SYS_EXTRACT_UTC(SYSTIMESTAMP) FROM DUAL
サマータイムを考慮するには、次の 2 つのオプションがあります。
EST タイム ゾーンのみをサポートする必要がある場合は、関数を作成することをお勧めします。それ以外の場合は、タイム ゾーンによって異なるため、これらの日付を含むテーブルを作成することをお勧めします。
これを試して:
CREATE TABLE TIMEZONES (ZONE CHAR(1) PRIMARY KEY,
NAMES VARCHAR2(25) NOT NULL,
OFFSET_HOURS NUMBER NOT NULL);
次のように入力します。
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('Z', 'GMT', 0);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('N', '-1', -1);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('O', '-2', -2);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('P', '-3', -3);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('Q', '-4 EDT', -4);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('R', 'EST CDT', -5);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('S', 'CST MDT', -6);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('T', 'MST PDT', -7);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('U', 'PST', -8);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('V', '-9', -9);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('W', '-10', -10);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('X', '-11', -11);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('Y', '-12', -12);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('A', '1', -1);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('B', '2', -2);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('C', '3', -3);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('D', '4', -4);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('E', '5', -5);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('F', '6', -6);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('G', '7', -7);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('H', '8', -8);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('I', '9', -9);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('K', '10', -10);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('L', '11', -11);
INSERT INTO TIMEZONES (ZONE, NAMES, OFFSET_HOURS) VALUES ('M', '12', -12);
上記を考えると、次のことができます
SELECT SYS_EXTRACT_UTC(SYSTIMESTAMP) + (tz.OFFSET_HOURS / 24)
FROM TIMEZONES tz
WHERE tz.NAMES LIKE '%EDT%';
また
WHERE tz.ZONE = 'Q'
-4タイムゾーンで現地時間を取得します。
共有してお楽しみください。
現在のタイムスタンプを操作する場合、これまでの方法はすべてうまく機能します。tz_offset
しかし、オラクルが一般的な時間オフセットを提供することに気付きました。たとえば、7 月には、
SELECT TZ_OFFSET('US/Eastern') FROM DUAL;
「-04:00」になります。1 月では、同じステートメントの結果は「-05:00」になります。そのため、(現在のシステムまたはセッション時間ではなく) データベースに格納されている日付を変換する場合は、いくつかの開発を行う必要があります。
あなたはそれに気付くかもしれません
SELECT TZ_OFFSET('EST') FROM DUAL;
常に「-05:00」を返します。残念ながら、他の米国標準時 (中央、山岳、太平洋) を簡単にテストすると、異なる結果が示されました。以下を実行して、自分の目で確かめてください。DST が有効な 6 月 16 日に、次のコマンドを実行しました。
SELECT TZ_OFFSET('US/Eastern'), TZ_OFFSET('EST'), TZ_OFFSET('EST5EDT') FROM DUAL;
SELECT TZ_OFFSET('US/Central'), TZ_OFFSET('CST'), TZ_OFFSET('CST6CDT') FROM DUAL;
SELECT TZ_OFFSET('US/Mountain'), TZ_OFFSET('MST'), TZ_OFFSET('MST7MDT') FROM DUAL;
SELECT TZ_OFFSET('US/Pacific'), TZ_OFFSET('PST'), TZ_OFFSET('PST8PDT') FROM DUAL;
-04:00 -05:00 -04:00
-05:00 -05:00 -05:00
-06:00 -07:00 -06:00
-07:00 -07:00 -07:00
結果はややイライラします。簡単なサンプリングから、ほとんどすべての tz_offset クエリが現在の一般的な時間で応答するように見えます。これは、現在の時刻の変換を使用している場合に便利ですが、データベースから取得した時刻を使用している場合はうまくいきません。
これで、現在が標準時間か標準時間かを判断するコードを記述できるようになりました。tz_offset
ただし、標準時間または夏時間に対して 一貫して a を取得する方法はありません。
これにより、開発者は、Bob Jarvis が上記のように独自のテーブルを作成して問題を回避し、以下のコードで行ったように、独自のテーブルを作成する必要が生じます。
ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/YYYY HH24:MI:SS';
Declare
-- ******** User declarations begin here ******** --
-- ******** User declarations end here ******** --
/******************* All Declarations of Variables and Functions below this point support Time Zone Conversion (Convert_TZ function) *******************/
-- TimeZone Conversion Procedure
-- User Input (Parameters)
input_date date := TO_TIMESTAMP_TZ('7/1/2009 18:00','mm/dd/yyyy hh24:mi'); -- Try: LocalTimestamp; or TO_TIMESTAMP('2/1/2009 13:00','mm/dd/yyyy hh24:mi')
--input_date date := LocalTimestamp;
input_TZ varchar(3) := 'GMT'; -- Exmaples: EST, EDT or EPT for Eastern Standard, Daylight or Prevailing, respectively.
output_TZ varchar(3) := 'EPT'; --
-- Variables
type date_array is table of date;
return_date date := localtimestamp;
temp_date date := to_date('10/27/1974 02:00','mm/dd/yyyy hh24:mi');
type str_array is table of varchar2(10);
dow_list str_array;
Function dst_start_stop (input_date DATE)
RETURN date_array
AS
year_part number(4);
start_week number(1) := 0; -- week of month: -1=last, 1=1st, 2=nd, 0=fixed date (like 1974 and 1975)
stop_week number(1) := 0; -- week of month: -1=last, 1=1st, 2=nd, 0=fixed date (like 1974 and 1975)
dst_start date := to_date('01/06/1974 23:59','mm/dd/yyyy hh24:mi');
dst_stop date := to_date('10/27/1974 23:59','mm/dd/yyyy hh24:mi');
dst_date date := dst_start;
dst_msg varchar2(500) := ' ';
inc_dec number := 0;
Cnt number(1) := 0;
dst_dow number(1) := 1; -- 1=Sunday, 2=Monday, etc.
i number;
dst_range date_array;
BEGIN
dst_range := date_array();
dst_range.extend(2);
dst_range(1) := temp_date;
dst_range(2) := temp_date;
DBMS_OUTPUT.PUT_LINE(' ** Start: dst_start_stop Func **');
--insert into dst_range values(dst_start,dst_stop);
--dst_range(1) := dst_start;
--dst_range(2) := dst_stop;
year_part := to_number(to_char(input_date,'YYYY'));
DBMS_OUTPUT.PUT_LINE(' Year: '||year_part);
-- Determine DST formula based on year of input_date
If year_part > 9999 Then -- Invalid TempYear > 9999
dst_msg := 'N/A. I can''t guess if DST will be applied after 9999. Standard Time returned. ';
Goto found_start_stop;
ElsIf year_part >= 2007 Then -- 2007 forward. Latest DST Rules used after 2007.
dst_msg := '2007 forward: Third National DST Standard. ';
--dst_msg := dst_msg || 'Spring Forward 2:00 AM second Sunday in March (skip 02:00:00 through 02:59:59, I.E. skip from 01:59:59 to 03:00:00). '
--dst_msg := dst_msg || 'Fall Back 2:00 AM first Sunday in November (repeat 02:00:00 to 02:59:59, I.E. jump back from 02:59:59 to 02:00:00 once). '
DBMS_OUTPUT.PUT_LINE(' '||dst_msg);
dst_start := to_date('03/01/'||year_part||' 02:00','mm/dd/yyyy hh24:mi');
start_week := 2; -- 2nd Sunday in March
dst_stop := to_date('11/01/'||year_part||' 02:00','mm/dd/yyyy hh24:mi');
stop_week := 1; -- 1st Sunday in November
ElsIf year_part >= 1987 Then -- 1987 thru 2006.
dst_msg := '1987 thru 2006: Second National DST Standard. ';
--dst_msg := dst_msg || 'Spring Forward 2:00 AM first Sunday in April (skip 02:00:00 through 02:59:59, I.E. skip from 01:59:59 to 03:00:00). ';
--dst_msg := dst_msg || 'Fall Back 2:00 AM last Sunday in October (repeat 02:00:00 to 02:59:59, I.E. jump back from 02:59:59 to 02:00:00 once). ';
DBMS_OUTPUT.PUT_LINE(' '||dst_msg);
start_week := 1;
dst_start := to_date('04/01/'||year_part||' 02:00','mm/dd/yyyy hh24:mi');
stop_week := -1;
dst_stop := to_date('10/31/'||year_part||' 02:00','mm/dd/yyyy hh24:mi');
ElsIf year_part >= 1976 Then -- 1976 thru 1986 OLD DST Rules used 1961 thru 1973.
dst_msg := '1976 thru 1986: First National DST Standard (resumed after 1974-1975 extended DST trials). ';
--dst_msg := dst_msg || 'Spring Forward 2:00 AM last Sunday in April (skip 02:00:00 through 02:59:59, I.E. skip from 01:59:59 to 03:00:00). ';
--dst_msg := dst_msg || 'Fall Back 2:00 AM last Sunday in October (repeat 02:00:00 to 02:59:59, I.E. jump back from 02:59:59 to 02:00:00 once). ';
DBMS_OUTPUT.PUT_LINE(' '||dst_msg);
start_week := -1;
dst_start := to_date('04/30/'||year_part||' 02:00','mm/dd/yyyy hh24:mi');
stop_week := -1;
dst_stop := to_date('10/31/'||year_part||' 02:00','mm/dd/yyyy hh24:mi');
ElsIf year_part = 1975 Then -- 1975 Trial.
dst_msg := '1975 Trial of Extended DST. ';
--dst_msg := dst_msg || 'Spring Forward 2:00 AM Feb 23 (skip 02:00:00 through 02:59:59, I.E. skip from 01:59:59 to 03:00:00). ';
--dst_msg := dst_msg || 'Fall Back 2:00 AM Oct 26, the last Sun in Oct (repeat 02:00:00 to 02:59:59, I.E. jump back from 02:59:59 to 02:00:00 once). ';
DBMS_OUTPUT.PUT_LINE(' '||dst_msg);
dst_start := to_date('02/23/1975 02:00','mm/dd/yyyy hh24:mi');
dst_stop := to_date('10/26/1974 02:00','mm/dd/yyyy hh24:mi');
Goto found_start_stop;
ElsIf year_part = 1974 Then -- 1974 Trial.
dst_msg := '1974 Trial of Extended DST. ';
--dst_msg := dst_msg || 'Spring Forward 2:00 AM Jan 6 (skip 02:00:00 through 02:59:59, I.E. skip from 01:59:59 to 03:00:00)). ';
--dst_msg := dst_msg || 'Fall Back 2:00 AM Oct 27 (repeat 02:00:00 to 02:59:59, I.E. jump back from 02:59:59 to 02:00:00 once). ';
DBMS_OUTPUT.PUT_LINE(' '||dst_msg);
dst_start := to_date('01/06/1974 02:00','mm/dd/yyyy hh24:mi');
dst_stop := to_date('10/27/1974 02:00','mm/dd/yyyy hh24:mi');
Goto found_start_stop;
ElsIf year_part >= 1961 Then -- 1961 thru 1973 First National DST Standard.
dst_msg := '1961 thru 1973: First National DST Standard. ';
--dst_msg := dst_msg || 'Spring Forward 2:00 AM last Sunday in April (skip 02:00:00 through 02:59:59, I.E. skip from 01:59:59 to 03:00:00). ';
--dst_msg := dst_msg || 'Fall Back 2:00 AM last Sunday in October (repeat 02:00:00 to 02:59:59, I.E. jump back from 02:59:59 to 02:00:00 once). ';
start_week := -1;
dst_start := to_date('04/30/'||input_date||' 02:00','mm/dd/yyyy hh24:mi');
stop_week := -1;
dst_stop := to_date('10/31/'||year_part||' 02:00','mm/dd/yyyy hh24:mi');
ElsIf year_part >=1900 Then -- DST was applied inconsistently or not at all
dst_msg := 'N/A. Before 1961, DST was applied inconsistently across states or not at all. Standard Time returned. ';
Goto found_start_stop;
ElsIf year_part < 1900 Then -- Invalid year_part
dst_msg := 'N/A. DST never active before 1900';
Goto found_start_stop;
Else -- Invalid year_part
dst_msg := 'N/A. Error. Invalid datetime value.';
Goto found_start_stop;
End If;
DBMS_OUTPUT.PUT_LINE(' The code specified the following DST rules for the input date ('||input_date||'). '||dst_msg);
if start_week > 0 then
DBMS_OUTPUT.PUT_LINE(' Start on '||dow_list(dst_dow)||' #'||start_week||' of '||trunc(dst_start,'W')||'. ');
else
DBMS_OUTPUT.PUT_LINE(' Starts '||start_week||' from the last '||dow_list(dst_dow)||' of '||trunc(dst_start,'W')||'. ');
end if;
if stop_week > 0 then
DBMS_OUTPUT.PUT_LINE(' End on '||dow_list(dst_dow)||' #'||stop_week||' of '||trunc(dst_stop,'W')||'. ');
else
DBMS_OUTPUT.PUT_LINE(' Ends '||stop_week||' from the last '||dow_list(dst_dow)||' of '||trunc(dst_stop,'W')||'. ');
end if;
DBMS_OUTPUT.PUT_LINE(' ');
/* Apply formula determined above to find dst start and stop times for the year of the input_date.
This section is skipped if start/stop already determined or indeterminant.
*/
-- DstStartDay
inc_dec := start_week/abs(start_week); -- results in +1 or -1
Cnt := 0; i:=0;
while (Cnt < abs(start_week) and i<20) loop
i:=i+1;
if (to_char(dst_start,'D') = dst_dow) then
Cnt := Cnt + 1;
--DBMS_OUTPUT.PUT_LINE(' Found '||dow_list(dst_dow))||' '||Cnt||': '||dst_start)
end if;
if (Cnt < abs(start_week)) then
dst_start := dst_start + inc_dec;
end if;
end loop;
case inc_dec
when 1 then
DBMS_OUTPUT.PUT_LINE(' Spring forward on '||dow_list(dst_dow)||' #'||Cnt||' of the month: '||dst_start);
else
DBMS_OUTPUT.PUT_LINE(' Spring forward on the last'||dow_list(dst_dow)||'of the month: '||dst_start);
end case;
-- DstStopDay
inc_dec := stop_week/abs(stop_week); -- results in +1 or -1
Cnt := 0; i :=0;
while (Cnt < abs(stop_week) and i <20) loop -- to_char(dst_stop,'D') > 1 loop
i:=i+1;
if (to_char(dst_stop,'D') = dst_dow) then
dst_stop := dst_stop + inc_dec;
Cnt := Cnt + 1;
end if;
if (Cnt < abs(stop_week)) then
dst_stop := dst_stop + inc_dec;
end if;
end loop;
case inc_dec
when 1 then
DBMS_OUTPUT.PUT_LINE(' Fall back on '||dow_list(dst_dow)||' #'||Cnt||' of the month: '||dst_stop);
else
DBMS_OUTPUT.PUT_LINE(' Fall back on the last'||dow_list(dst_dow)||'of the month: '||dst_stop);
end case;
<<found_start_stop>>
dst_range(1) := dst_start;
DBMS_OUTPUT.PUT_LINE(' dst_range(1): '||to_char(dst_range(1),'mm/dd/yyyy hh24:mi')||' = '||dst_start);
dst_range(2) := dst_stop;
DBMS_OUTPUT.PUT_LINE(' dst_range(2): '||to_char(dst_range(2),'mm/dd/yyyy hh24:mi')||' = '||dst_stop);
DBMS_OUTPUT.PUT_LINE(' ** Finish: dst_start_stop Func **');
Return dst_range;
END dst_start_stop;
Function is_dst_now
Return boolean
AS
--type date_array is table of date;
dst_range date_array;
curr_time date := LocalTimestamp;
Begin
dst_range := date_array();
dst_range.extend(2);
dst_range := dst_start_stop(curr_time);
If (dst_range(1) <= curr_time and curr_time < dst_range(2)) then
DBMS_OUTPUT.PUT_LINE('DST is active.');
Return True;
Else
DBMS_OUTPUT.PUT_LINE('DST is NOT active.');
Return False;
End If;
End;
FUNCTION dst_offset (prevailing_date DATE, dst_start DATE, dst_stop DATE)
RETURN number
AS
offset_days number :=0;
BEGIN
DBMS_OUTPUT.PUT_LINE(' Starting dst_offset sub-function:');
DBMS_OUTPUT.PUT_LINE(' where (input date, DST start, DST stop) = '||to_char(prevailing_date,'mm/dd/yyyy hh24:mi')
||', '||to_char(dst_start,'mm/dd/yyyy hh24:mi')||', '||to_char(dst_stop,'mm/dd/yyyy hh24:mi'));
If (dst_start <= prevailing_date and prevailing_date < dst_stop) then
offset_days :=1/24;
DBMS_OUTPUT.PUT_LINE(' input date is between dst start and stop');
Else
offset_days :=0;
DBMS_OUTPUT.PUT_LINE(' input date is not between dst start and stop');
End If;
DBMS_OUTPUT.PUT_LINE(' Result: DST Offset days = '||offset_days);
DBMS_OUTPUT.PUT_LINE(' hours = '||(offset_days*24));
Return offset_days;
END dst_offset;
-- Begin --move this down under the function -- ******************
FUNCTION Convert_TZ (input_date DATE, input_tz varchar2, output_tz varchar2)
RETURN date
AS
-- Variables
input_sz varchar(3) := substr(input_TZ,1,1)||'S'||substr(input_TZ,3,1);
input_sz varchar(3) := substr(output_TZ,1,1)||'S'||substr(output_TZ,3,1);
temp_str varchar2(1000);
dst_range date_array;
input_dst_offset number := 0;
input_tz_offset number := 0;
input_date_st date; --standard time
gmt_date date;
output_dst_offset number := 0;
output_tz_offset number := 0;
output_date date;
output_date_pt date; -- prevailing time
tz_offset_str varchar2(30);
--orig_nls_date_format varchar2(30) := NLS_DATE_FORMAT;
--TempYear number(4,0) := to_char(TempDate,'YYYY'); -- or := trunc(PrevailingTime, YYYY);
BEGIN
DBMS_OUTPUT.PUT_LINE('Starting Pl/sql procedure. ');
DBMS_OUTPUT.PUT_LINE('Input Date: '||to_char(input_date,'mm/dd/yyyy hh24:mi')||' '||input_tz||'. ');
-- Find DST start/stop dates
dst_range := date_array();
dst_range.extend(2);
dst_range := dst_start_stop(input_date);
DBMS_OUTPUT.PUT_LINE('DST date range determined. ');
DBMS_OUTPUT.PUT_LINE(' dst_range(1): '||to_char(dst_range(1),'mm/dd/yyyy hh24:mi')||' = '||dst_range(1));
DBMS_OUTPUT.PUT_LINE(' dst_range(2): '||to_char(dst_range(2),'mm/dd/yyyy hh24:mi')||' = '||dst_range(2));
-- Convert Input Date from input time zone to GMT
If upper(input_TZ) in ('GMT','UCT') then
-- If input TZ is GMT, we can skip this conversion!
DBMS_OUTPUT.PUT_LINE(' Input Time is ('||to_char(input_date,'mm/dd/yyyy hh24:mi')||' '
||input_tz||' GMT). No conversion required. ');
input_tz_offset := 0;
input_dst_offset := 0;
gmt_date := input_date;
Else
-- Convert from local prevailing to local standard time
-- Get input_dst_offset
Case upper(substr(input_TZ,2,1))
When 'S' then
-- already in standard time, not conversion needed.
input_dst_offset := 0; -- duplicative
DBMS_OUTPUT.PUT_LINE('Standard time ('||input_tz||') entered; no dst offset.' );
--input_tz_offset := input_tz_offset;
Else
-- run dst_offset function to convert from prevailing or daylight time to standard time.
input_dst_offset := dst_offset(input_date, dst_range(1), dst_range(2));
input_date_st := input_date - input_dst_offset;
DBMS_OUTPUT.PUT_LINE('Daylight Saving Time Effective ('||to_char(input_date,'mm/dd/yyyy hh24:mi')||' '
||input_tz||'); 1 hour offset; input DST offset = '||input_dst_offset);
DBMS_OUTPUT.PUT_LINE(' where (input_date, dst_start, dst_stop) = '
||to_char(input_date,'mm/dd/yyyy hh24:mi')
||' '||input_tz||', '||dst_range(1)||', '||dst_range(2)||', ');
DBMS_OUTPUT.PUT_LINE(' which adjusts '||to_char(input_date,'mm/dd/yyyy hh24:mi')||' '||input_tz
||' daylight to '||input_date_st||' standard time. ');
End Case;
-- Convert from local standard time to GMT
SELECT TZ_OFFSET((SELECT max(tzname) FROM V$TIMEZONE_NAMES where tzabbrev = input_TZ))
INTO tz_offset_str
FROM DUAL;
input_tz_offset := ( substr(tz_offset_str,1,3)/24 + substr(tz_offset_str,5,2)/1440 );
If is_dst_now then
input_tz_offset := input_tz_offset - 1/24;
End if;
DBMS_OUTPUT.PUT_LINE(' input_tz_offset (fractional days): '||input_tz_offset||'. ');
DBMS_OUTPUT.PUT_LINE(' input_tz_offset (hours): '||input_tz_offset*24||'. ');
gmt_date := input_date_st - input_tz_offset;
End If;
-- Convert input date from GMT to requested output time zone
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('Starting output_date analysis. ');
If upper(output_TZ) in ('GMT','UCT') then
-- If desired output TZ is GMT, we can skip this conversion!
output_tz_offset := 0;
output_dst_offset := 0;
output_date := gmt_date;
DBMS_OUTPUT.PUT_LINE(' Requested output format is GMT: ('||to_char(output_date,'mm/dd/yyyy hh24:mi')||' '||output_tz||'). No conversion required. ');
Else
-- Get output_dst_offset
Case upper(substr(output_TZ,2,1))
When 'S' then
output_dst_offset := 0; -- duplicative
DBMS_OUTPUT.PUT_LINE('Standard time ('||output_TZ||') entered; no dst offset.' );
Else
output_dst_offset := dst_offset(gmt_date + output_tz_offset, dst_range(1), dst_range(2));
End Case;
-- Convert from GMT to local standard time
SELECT TZ_OFFSET((SELECT max(tzname) FROM V$TIMEZONE_NAMES where tzabbrev = output_TZ)) INTO tz_offset_str FROM DUAL;
output_tz_offset := ( substr(tz_offset_str,1,3)/24 + substr(tz_offset_str,5,2)/1440 );
DBMS_OUTPUT.PUT_LINE(' output_tz_offset (fractional days): '||output_tz_offset||'. ');
DBMS_OUTPUT.PUT_LINE(' output_tz_offset (hours): '||output_tz_offset*24||'. ');
If is_dst_now then
output_tz_offset := output_tz_offset - 1/24;
DBMS_OUTPUT.PUT_LINE(' tz_offset correction... ');
DBMS_OUTPUT.PUT_LINE(' output_tz_offset (fractional days): '||output_tz_offset||'. ');
DBMS_OUTPUT.PUT_LINE(' output_tz_offset (hours): '||output_tz_offset*24||'. ');
End if;
output_date := gmt_date + output_tz_offset + output_dst_offset;
DBMS_OUTPUT.PUT_LINE(' gmt_date: '||gmt_date);
DBMS_OUTPUT.PUT_LINE(' output_tz_offset: '||output_tz_offset);
DBMS_OUTPUT.PUT_LINE(' output_dst_offset: '||output_dst_offset);
DBMS_OUTPUT.PUT_LINE('Daylight Saving Time ('||output_TZ||') offset = '||output_dst_offset);
DBMS_OUTPUT.PUT_LINE(' where (output_date, dst_start, DST_stop) = '||output_date||', '||dst_range(1)||', '||dst_range(2));
DBMS_OUTPUT.PUT_LINE(' which adjusts '||output_date||' standard to '||output_date_pt||' daylight time. ');
End If;
DBMS_OUTPUT.PUT_LINE('Output Date = '||to_char(output_date,'mm/dd/yyyy hh24:mi')||' '||output_tz||'. ');
Goto AllDone;
<<FoundError>>
<<AllDone>>
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('*** Results ***');
DBMS_OUTPUT.PUT_LINE(' ');
if input_dst_offset <> 0 then
temp_str := 'daylight saving';
else
temp_str := 'standard';
end if;
DBMS_OUTPUT.PUT_LINE(' Input Date: '||to_char(input_date,'mm/dd/yyyy hh24:mi')||' '||input_tz||', which falls in '||temp_str||' time. ');
DBMS_OUTPUT.PUT_LINE(' GMT Date: '||to_char(gmt_date,'mm/dd/yyyy hh24:mi')||' UTC/GMT. ');
DBMS_OUTPUT.PUT_LINE(' Output Date: '||to_char(output_date,'mm/dd/yyyy hh24:mi')||' UTC/GMT. ');
if output_dst_offset <> 0 then
temp_str := 'daylight saving';
else
temp_str := 'standard';
end if;
DBMS_OUTPUT.PUT_LINE(' All Done. Return Value: '||to_char(output_date,'mm/dd/yyyy hh24:mi')||' '||output_tz||'. ');
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('*** End of Results ***');
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('LocalTimestamp EPT: '||LocalTimestamp);
DBMS_OUTPUT.PUT_LINE('LocalTimestamp GMT:'||LOCALTIMESTAMP at time zone '+00:00');
Return output_date;
END;
/*********************** End of Declarations of Variables and Functions for Time Zone Conversion (Convert_TZ function) *********************/
Begin
/*********************** Start of Procedural Code for Time Zone Conversion (Convert_TZ function) *********************/
/* DOW list is required for Time Zone Conversion (Convert_TZ function) and should not be deleted. */
dow_list := str_array();
dow_list.extend(7);
dow_list(1) := 'Sun';
dow_list(2) := 'Mon';
dow_list(3) := 'Tue';
dow_list(4) := 'Wed';
dow_list(5) := 'Thu';
dow_list(6) := 'Fri';
dow_list(7) := 'Sat';
/* Next 2 lines are example of use of Time Zone Conversion (Convert_TZ function). */
return_date := Convert_TZ (input_date, input_tz, output_tz);
DBMS_OUTPUT.PUT_LINE('ta-dah! '||return_date);
/*********************** End of Procedural Code for Time Zone Conversion (Convert_TZ function) *********************/
-- ******** User coded begins here ******** --
End;