2012-02-09 8 views
0

私は日付をUnixタイムスタンプに変換する関数を書いています。この関数は、現在の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関数からスローされています。 、これはまだtz'UNK'に設定された状態で失敗した場合を除き

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; 

だから、私はそうのように、この問題のための回避策を実施しました。誰でもここで起こっていることを知っていますか?関数が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; 

注関数の2番目のパラメータの添加。このパラメータはin_src_tzで、in_dateのタイムゾーンを示すために使用されます。in_src_tzの値は、v$timezone_namesテーブルのtzname列に記載されているタイムゾーンのいずれかにする必要があります。

また、v$timezone_namesテーブルのtzabbrev列の値を複数の省略形を持つタイムゾーンのために選択することはできません。この抽出を使用すると、DSTを組み込んだ現在の省略形が取得されます。

0

これは、渡す日付パラメータに依存しないと思います。これはおそらくデータベースサーバーが動作するオペレーティングシステムの設定に依存します。 JDeveloperでは、おそらくコンピュータ(OS)のタイムゾーン設定から取得しています。 DBサーバー上でsshを実行し、スクリプト内の最初の2つのクエリを実行してください(最初のクエリでは '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経由でこれらのクエリを実行すると、Webページを処理するユーザーはエラーになりません。 –

0

ローカルマシンとサーバーでNLS_DATE_FORMATを比較しましたか?この違いの組み合わせと、日付が渡されたときに暗黙の変換が行われている可能性がある場合は、ここで問題になる可能性があります。

関連する問題