Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle Can';当使用mod_plsql时,是否无法获取时区信息?_Oracle_Plsql_Mod Plsql - Fatal编程技术网

Oracle Can';当使用mod_plsql时,是否无法获取时区信息?

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

我编写了一个函数,将日期转换为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 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;