Oracle Can';当使用mod_plsql时,是否无法获取时区信息?
我编写了一个函数,将日期转换为Unix时间戳。无论当前DST状态如何(例如EST或EDT),该函数都被写入工作状态。这就是功能:Oracle Can';当使用mod_plsql时,是否无法获取时区信息?,oracle,plsql,mod-plsql,Oracle,Plsql,Mod Plsql,我编写了一个函数,将日期转换为Unix时间戳。无论当前DST状态如何(例如EST或EDT),该函数都被写入工作状态。这就是功能: 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 th
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:不是有效时区
。由于tz
设置为'UNK'
,因此从new\u 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进程调用函数时,为什么不能获取本地时区缩写?我想这并不取决于您传递的日期参数。这可能取决于数据库服务器运行的操作系统设置。在JDeveloper中,它可能是从您的计算机(OS)时区设置中获取的。尝试在DB服务器上执行ssh,并在脚本中运行前两个查询(第一个查询使用'DD-MON-YY'格式的实际日期)。两者都应该返回“UNK”。UNK(未知)可能是因为返回了多个时区。示例:在以下示例中,假设当前时区为CST(美国中央时间)
您是否比较了本地计算机和服务器上的NLS_DATE_格式?您可能会发现,这方面的差异以及传入日期时发生IMPICT转换的可能性可能是您的问题。当调用它的会话未设置时区信息时,编写的函数不起作用。因此,您需要显式指定源时区。以下函数可解决此问题(并更正返回类型): 请注意,在函数中添加了第二个参数。此参数在_src _tz中为
,用于指示日期
中的参数所处的时区。_src_tz
中的值应为v$timezone_names
表的tzname
列中列出的时区之一
此外,由于时区有多个缩写,您不能简单地选择v$timezone_names
表中tzabbrev
列的值。通过使用摘录,您将获得包含DST的当前缩写。在OAS服务器上通过sqlplus执行这些查询,因为为网页提供服务的用户不会导致任何错误。
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.
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;