2012-02-09 5 views
0

날짜를 유닉스 타임 스탬프로 변환하는 함수를 작성했습니다. 이 함수는 현재 DST 상태 (예 : EST 또는 EDT)와 상관없이 작동하도록 작성되었습니다. 이 함수는 다음과 같습니다.mod_plsql을 사용할 때 표준 시간대 정보를 가져올 수 없습니까?

function unix_time_from_date(in_date in date) return number 
as 
    ut number  := 0; 
    tz varchar2(8) := ''; 
begin 
    -- Get the local timezone from the passed in date 
    -- Assuming the date supplied is for the local time zone 
    select 
    extract(
     timezone_abbr from cast(in_date as timestamp with local time zone) 
    ) 
    into tz 
    from dual; 

    -- Get the Unix timestamp 
    select 
    (new_time(in_date, tz, 'GMT') - to_date('01-JAN-1970', 'DD-MM-YYYY')) * (
    86400) 
    into ut 
    from dual; 

    return ut; 
end unix_time_from_date; 

이 함수는 JDeveloper와 같은 클라이언트에서 실행할 때 유용합니다. 클라이언트가 첫 번째 쿼리에 표준 시간대 정보를 제공하기 때문에 내가 수집 한 것부터 시작합니다. 그러나 mod_plsql 페이지에서 호출 된 프로 시저 내에서 함수를 사용하면 오류 ORA-01857: not a valid time zone이 발생합니다. tz'UNK'으로 설정되어 있기 때문에이 오류는 new_time 함수에서 발생합니다.

그래서, 난과 같이이 문제에 대한 해결 방법 구현 :

제외
function unix_time_from_date(in_date in date) return number 
as 
    ut number  := 0; 
    tz varchar2(8) := ''; 
begin 
    -- Get the local timezone from the passed in date 
    -- Assuming the date supplied is for the local time zone 
    select 
    extract(
     timezone_abbr from cast(in_date as timestamp with local time zone) 
    ) 
    into tz 
    from dual; 

    if tz = 'UNK' then 
    select 
     extract(
     timezone_abbr from cast(sysdate as timestamp with local time zone) 
    ) 
    into tz 
    from dual; 
    end if; 

    -- Get the Unix timestamp 
    select 
    (new_time(in_date, tz, 'GMT') - to_date('01-JAN-1970', 'DD-MM-YYYY')) * (
    86400) 
    into ut 
    from dual; 

    return ut; 
end unix_time_from_date; 

이 여전히 tz'UNK'로 설정하고 실패합니다. 아무도 여기서 무슨 일이 일어날 지 알고 있습니까? Oracle Application Server 프로세스에서 함수를 호출 할 때 현지 시간대 약어를 얻을 수없는 이유는 무엇입니까?

답변

0

세션을 호출하는 세션에 표준 시간대 정보가 설정되어 있지 않으면 작성된 함수가 작동하지 않습니다. 따라서 명시 적으로 소스 시간대를 지정해야합니다. 다음 함수는이 문제를 해결하고 반환 유형을 수정합니다.

function unix_time_from_date 
    (
     in_date in date, 
     in_src_tz in varchar2 default 'America/New_York' 
    ) 
    return integer 
as 
    ut  integer  := 0; 
    tz  varchar2(8) := ''; 
    tz_date timestamp with time zone; 
    tz_stmt varchar2(255); 
begin 
    -- Get the local time zone abbreviation from the passed in date 
    tz_stmt := 'select systimestamp at time zone ''' || in_src_tz || ''' from dual'; 
    execute immediate tz_stmt into tz_date; 
    select 
    extract(timezone_abbr from tz_date) 
    into tz 
    from dual; 

    -- Get the Unix timestamp 
    select 
    (new_time(in_date, tz, 'GMT') - to_date('01-JAN-1970', 'DD-MM-YYYY')) * (86400) 
    into ut 
    from dual; 

    return ut; 
end unix_time_from_date; 

함수에 두 번째 매개 변수가 추가되었습니다. 이 매개 변수 in_src_tzin_date 매개 변수가있는 표준 시간대를 나타내는 데 사용됩니다. in_src_tz 값은 v$timezone_names 테이블의 tzname 열에 나열된 시간대 중 하나 여야합니다.

또한 v$timezone_names 테이블에있는 복수의 약어가있는 시간대로 인해 tzabbrev 열의 값을 간단하게 선택할 수 없습니다. 추출을 사용하면 DST가 포함 된 현재 약어가 표시됩니다.

0

나는 이것이 당신이 지나가는 날짜 매개 변수에 의존하지 않는다고 생각합니다. 데이터베이스 서버가 실행되는 운영 체제 설정에 따라 달라집니다. JDeveloper에서는 아마 컴퓨터 (OS) 시간대 설정에서 선택됩니다. DB 서버에서 ssh을 실행하고 스크립트에서 처음 두 쿼리를 실행하십시오 (첫 번째 쿼리의 경우 'DD-MON-YY'형식의 실제 날짜 사용). 둘 다 'UNK'를 반환해야합니다. UNK (알 수 없음)는 두 개 이상의 시간대가 반환되기 때문에 발생합니다. 예제 : 다음 예제에서는 현재 시간대가 CST (미국 중부 표준시)라고 가정합니다.

SELECT NEW_TIME(SYSDATE, 'CST', 'GMT') FROM DUAL --returns the date in London. 

SELECT TO_CHAR(NEW_TIME(SYSDATE, 'CST', 'GMT'),'HH24:MI') FROM DUAL --returns the time, based on the 24-hour clock, in London. 

SELECT TO_CHAR(NEW_TIME(SYSDATE + (14/24), 'PST', 'PST'),'DD-MON-YY HH24:MI') FROM DUAL --returns the date and time in China. 

SELECT TO_CHAR(NEW_TIME(SYSDATE + (diff/24), ‘GMT’, ‘GMT’),’DD-MON-YY HH24:MI’) FROM DUAL; --returns the date and time of your office. 
+0

OAS 서버에서 sqlplus를 통해 이러한 쿼리를 실행하면 웹 페이지를 제공하는 사용자는 오류가 발생하지 않습니다. –

0

로컬 시스템과 서버에서 NLS_DATE_FORMAT를 비교 했습니까? 이 점의 차이점과 날짜가 전달 될 때 암묵적인 전환이 일어날 가능성이있는 경우 여기에서 문제가 될 수 있습니다.

관련 문제