Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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
将时间戳数据类型转换为unix时间戳Oracle_Oracle_Oracle10g_Unix Timestamp - Fatal编程技术网

将时间戳数据类型转换为unix时间戳Oracle

将时间戳数据类型转换为unix时间戳Oracle,oracle,oracle10g,unix-timestamp,Oracle,Oracle10g,Unix Timestamp,我在数据库中有一个格式为24-JuL-11 10.45.00.000000000 AM的时间戳数据类型,我想将其转换为unix时间戳,我如何获得它?这个问题与 正如贾斯汀·凯夫所说: 没有内置函数。但它相对容易写 一个。由于Unix时间戳是自1月1日起的秒数, 1970年 由于从另一个日期减去一个日期会产生两个日期之间的天数,因此您可以执行以下操作: create or replace function date_to_unix_ts( PDate in date ) return number

我在数据库中有一个格式为24-JuL-11 10.45.00.000000000 AM的时间戳数据类型,我想将其转换为unix时间戳,我如何获得它?

这个问题与

正如贾斯汀·凯夫所说:

没有内置函数。但它相对容易写 一个。由于Unix时间戳是自1月1日起的秒数, 1970年

由于从另一个日期减去一个日期会产生两个日期之间的天数,因此您可以执行以下操作:

create or replace function date_to_unix_ts( PDate in date ) return number is

   l_unix_ts number;

begin

   l_unix_ts := ( PDate - date '1970-01-01' ) * 60 * 60 * 24;
   return l_unix_ts;

end;
由于自1970年以来一直以秒为单位,分数秒的数量无关紧要。您仍然可以使用时间戳数据类型调用它

SQL> select date_to_unix_ts(systimestamp) from dual;

DATE_TO_UNIX_TS(SYSTIMESTAMP)
-----------------------------
                   1345801660

对于您的评论,我很抱歉,但我没有看到这种行为:

SQL> with the_dates as (
  2    select to_date('08-mar-12 01:00:00 am', 'dd-mon-yy hh:mi:ss am') as dt
  3      from dual
  4     union all
  5    select to_date('08-mar-12', 'dd-mon-yy')
  6      from dual )
  7  select date_to_unix_ts(dt)
  8    from the_dates
  9         ;

DATE_TO_UNIX_TS(DT)
-------------------
         1331168400
         1331164800

SQL>

有3600秒的差异,即1小时。

< P>我意识到答案已经被接受了,但是我想应该清楚,答案中的函数没有考虑过期日期的时区偏移。应在GMT(+0)计算正确的Unix时间戳。Oracle的
to_date
函数假定传入日期在本地时区,除非另有规定。夏令时是一个真实的事物,这一事实加剧了这个问题。我通过以下功能解决了此问题:

create or replace
  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
    /**
     * This function is used to convert an Oracle DATE (local timezone) to a Unix timestamp (UTC).
     *
     * @author James Sumners
     * @date 01 February 2012
     *
     * @param in_date An Oracle DATE to convert. It is assumed that this date will be in the local timezone.
     * @param in_src_tz Indicates the time zone of the in_date parameter.
     *
     * @return integer
     */

    -- Get the current timezone abbreviation (stupid DST)
    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;
我有一些配套功能,
unix\u-time
unix\u-time\u-to\u-date
,可从以下站点获得。我不敢相信Oracle在没有实现这些功能的情况下已经成功实现了11g。

关于日期:

   FUNCTION date_to_unix (p_date  date,in_src_tz in varchar2 default 'Europe/Kiev') return number is
begin
    return  round((cast((FROM_TZ(CAST(p_date as timestamp), in_src_tz) at time zone 'GMT') as date)-TO_DATE('01.01.1970','dd.mm.yyyy'))*(24*60*60));
end;
对于时间戳:

FUNCTION timestamp_to_unix (p_time  timestamp,in_src_tz in varchar2 default 'Europe/Kiev') return number is
    begin
        return  round((cast((FROM_TZ(p_time, in_src_tz) at time zone 'GMT') as date)-TO_DATE('01.01.1970','dd.mm.yyyy'))*(24*60*60));
    end;

这就是我想到的:

select    substr(extract(day from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 24 * 60 * 60 + 
          extract(hour from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 60 * 60 + 
          extract(minute from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 60 + 
          trunc(extract(second from (n.origstamp - timestamp '1970-01-01 00:00:00')),0),0,15) TimeStamp 
          from tablename;

FWIW

我使用下面的方法,它与其他答案稍有不同,因为它使用
sessiontimezone()
函数正确获取日期

    select
    ( 
      cast((FROM_TZ(CAST(in_date as timestamp), sessiontimezone) at time zone 'GMT') as date) -- in_date cast do GMT
      - 
      TO_DATE('01.01.1970','dd.mm.yyyy') -- minus unix start date
    )
    * 86400000 -- times miliseconds in day
    from dual;

对于Oracle时间和Unix时间之间的转换,我使用这些函数。 他们考虑你当前的时区。您还应该添加
DETERMINISTIC
关键字,例如,如果您希望在基于函数的索引中使用此类函数。
日期
时间戳
之间的转换应由Oracle隐式完成

FUNCTION Timestamp2UnixTime(theTimestamp IN TIMESTAMP, timezone IN VARCHAR2 DEFAULT SESSIONTIMEZONE) RETURN NUMBER DETERMINISTIC IS
    timestampUTC TIMESTAMP;
    theInterval INTERVAL DAY(9) TO SECOND;
    epoche NUMBER;
BEGIN
    timestampUTC := FROM_TZ(theTimestamp, timezone) AT TIME ZONE 'UTC';
    theInterval := TO_DSINTERVAL(timestampUTC - TIMESTAMP '1970-01-01 00:00:00');
    epoche := EXTRACT(DAY FROM theInterval)*24*60*60 
        + EXTRACT(HOUR FROM theInterval)*60*60 
        + EXTRACT(MINUTE FROM theInterval)*60 
        + EXTRACT(SECOND FROM theInterval);
    RETURN ROUND(epoche);
END Timestamp2UnixTime;



FUNCTION UnixTime2Timestamp(UnixTime IN NUMBER) RETURN TIMESTAMP DETERMINISTIC IS
BEGIN
    RETURN (TIMESTAMP '1970-01-01 00:00:00 UTC' + UnixTime * INTERVAL '1' SECOND) AT LOCAL;
END UnixTime2Timestamp;

我传递给PDate的值来自$sql=Select to_DATE(to_CHAR(fld_from_DATE,'DD-Mon-YY HH:MI:SS am'),'DD-Mon-YY HH:MI:SS am')作为unix时间戳的日期,假设上述查询结果中的to_CHAR(fld_from_DATE,'DD-Mon-YY HH:SS am'),假设为'08-Mar-12 01:00:00 am',这个字符的最新版本是'08-Mar-12',HH:MI:SS(01:00:00 AM)没有出现的原因是什么?嗨@deepti,没有必要发布另一个答案。您可以随时单击问题上的“编辑”链接,并在此处进行更改。评论也会给我留下通知。我已经更新了我的答案;缺乏可视性可能与您的客户机有关?研究时间和闰秒我必须说您的编程解决方案是正确的,但引用的Unix时间定义不是:Unix时间不是自1970年1月1日以来的秒数,而是“从1970年1月1日起的天数乘以60*60*24加上从今天午夜起的秒数!该函数不考虑当前时区。Unix时间戳是自1970年1月1日00:00:00 UTC以来的秒数。只有当您的本地时区是UTC时,结果才是正确的。我们建议您在代码中添加一些解释,特别是如果已经有很多答案,那么它与其他答案不同的原因不包括闰年、闰秒这似乎是微秒而不是秒。@GPHemsley,有些系统使用秒,有些则使用毫秒。如何更改它应该是相当明显的。标准Unix时间戳是从纪元开始以秒为单位的,问题并不表明需要对该标准进行任何更改。这个问题的所有其他答案都使用秒,而不是毫秒(这就是我的意思,而不是微秒)。如何更改答案可能是相当明显的,但答案是否需要更改并不是很明显的。没有理由使用动态SQL和
SELECT。。。从双通道进入
。只支持所有时区的一小部分,因此可能会失败。如果输入日期不在当前季节,也会失败,请从日期(SYSDATE+150)尝试
unix\u time\u。
SELECT (SYSDATE - TO_DATE('01-01-1970 00:00:00', 'DD-MM-YYYY HH24:MI:SS')) * 24 * 60 * 60 * 1000 FROM DUAL
FUNCTION Timestamp2UnixTime(theTimestamp IN TIMESTAMP, timezone IN VARCHAR2 DEFAULT SESSIONTIMEZONE) RETURN NUMBER DETERMINISTIC IS
    timestampUTC TIMESTAMP;
    theInterval INTERVAL DAY(9) TO SECOND;
    epoche NUMBER;
BEGIN
    timestampUTC := FROM_TZ(theTimestamp, timezone) AT TIME ZONE 'UTC';
    theInterval := TO_DSINTERVAL(timestampUTC - TIMESTAMP '1970-01-01 00:00:00');
    epoche := EXTRACT(DAY FROM theInterval)*24*60*60 
        + EXTRACT(HOUR FROM theInterval)*60*60 
        + EXTRACT(MINUTE FROM theInterval)*60 
        + EXTRACT(SECOND FROM theInterval);
    RETURN ROUND(epoche);
END Timestamp2UnixTime;



FUNCTION UnixTime2Timestamp(UnixTime IN NUMBER) RETURN TIMESTAMP DETERMINISTIC IS
BEGIN
    RETURN (TIMESTAMP '1970-01-01 00:00:00 UTC' + UnixTime * INTERVAL '1' SECOND) AT LOCAL;
END UnixTime2Timestamp;