截断时间戳

时间:2011-02-24 00:32:26

标签: sql oracle timestamp oracle11gr2

假设我有一个时间戳变量:

select timestamp '2011-02-24 08:30:42 +06:00' from dual;

有没有办法将它“截断”为类似

的东西
'2011-02-24 08:00:00 +06:00'

(我已经缩短了分钟和秒数,但离开了时区)

目标oracle版本是11g r2

4 个答案:

答案 0 :(得分:4)

SQL> select to_timestamp_tz(to_char(timestamp '2011-02-24 08:30:42 +06:00', 'YYYY-MM-DD HH24 TZH:TZM'), 'YYYY-MM-DD HH24 TZH:TZM') from dual;

TO_TIMESTAMP_TZ(TO_CHAR(TIMESTAMP'2011-02-2408:30:42+06:00','YYYY-MM-DDTZH:
---------------------------------------------------------------------------
24.02.2011 8:00:00,000000000 +06:00

答案 1 :(得分:1)

我用它来工作:

SELECT TO_TIMESTAMP_TZ(TO_CHAR(timestamp '2011-02-24 08:30:42 +06:00', 'YYYY-MM-DD HH24') || ':00:00 '|| TO_CHAR(timestamp '2011-02-24 08:30:42 +06:00', 'TZH:TZM'), 'YYYY-MM-DD HH24:MI:SS TZH:TZM')
  FROM DUAL

TRUNC支持timestamps 9.2.0.3+,但在我对10g Express Edition的测试中

SELECT TRUNC(timestamp '2011-02-24 08:30:42 +06:00', 'HH')
  FROM DUAL

......完全搞砸了小时和上午/下午。对于文字来说无关紧要,或者如果我为TO_TIMESTAMP_TZ提供了文字。针对10gR2的TRUNC(日期)文档说“返回的值始终为数据类型DATE,即使您为date指定了不同的datetime数据类型。”。

答案 2 :(得分:1)

您的NLS_DATE_FORMAT可能设置为仅显示日期部分。这对我有用:

SELECT 
    to_char( TRUNC(timestamp'2011-02-24 08:30:42 +06:00', 'HH'), 'YYYY-MM-DD HH24:MI:SS' )  
FROM DUAL;

请注意,返回的结果是DATE,因此您会丢失任何本地化信息。您可以通过将结果转换为时间戳来返回GMT标准化时间戳:

SELECT 
    to_char( from_tz( cast( TRUNC(timestamp'2011-02-24 08:30:42 +06:00' at time zone 'GMT', 'HH' ) as timestamp ), 'GMT' ), 'YYYY-MM-DD HH24:MI:SS TZR' )
FROM DUAL;

要保留时区信息,您必须做一些非常复杂的事情。在那时使用存储的函数执行转换可能更容易。这很像Oracle内置的TRUNC()函数:

create or replace function trunc_timestamp(
    ts  in timestamp_tz_unconstrained,
    fmt in varchar2 
)
return timestamp_tz_unconstrained
is
    tzone  varchar2(20);
begin
    tzone := extract( timezone_region from ts );
    if tzone = 'UNKNOWN' then
        tzone := to_char( extract( timezone_hour from ts ), 'fm09' ) 
          || ':' 
          || to_char( extract( timezone_minute from ts ), 'fm09' );
    end if;
    return from_tz( cast( TRUNC( ts at time zone tzone, fmt ) as timestamp ), tzone );
end;
/

我为演示创建了sqlfiddle

答案 3 :(得分:-1)

尝试select cast(timestamp as date) from dual