【问题标题】:TO_DATE ISSUE IN CONVERSIONTO_DATE 转换中的问题
【发布时间】:2017-12-12 07:56:51
【问题描述】:

我试图执行下面的查询,但它让我error:

SELECT TO_DATE(
        TIMESTAMP '1970-01-01 00:00:00' + numtodsinterval(1511421211, 'second')
        ,'DD-MM-YYYY HH24:MI:SS') 
FROM dual

错误:ORA-01830:日期格式图片在转换整个输入字符串之前结束

【问题讨论】:

  • 显然您正试图从this recent answer on unix timestamps in Oracle 运行代码,但由于某种原因您没有运行实际代码。无需使用 to_date() 将 TIMESTAMP 转换为 DATE:Oracle 只是为我们处理。
  • @APC 出于某种原因,它是一个新的网名。奇怪。
  • @Tim 我们都是坐在一边工作的朋友 :)

标签: oracle


【解决方案1】:

TO_DATE( datestring, format_model ) 函数将字符串作为参数。

您的查询:

SELECT TO_DATE(
        TIMESTAMP '1970-01-01 00:00:00' + numtodsinterval(1511421211, 'second')
        ,'DD-MM-YYYY HH24:MI:SS'
       ) 
FROM   dual

正在传递一个TIMESTAMP 和一个字符串,因此Oracle 必须执行从TIMESTAMP 到字符串的隐式转换,以便您的函数有效:

SELECT TO_DATE(
        TO_CHAR(
          TIMESTAMP '1970-01-01 00:00:00' + numtodsinterval(1511421211, 'second'),
          (
            SELECT value
            FROM NLS_SESSION_PARAMETERS
            WHERE parameter = 'NLS_TIMESTAMP_FORMAT'
          )
        ),
        'DD-MM-YYYY HH24:MI:SS'
       ) 
FROM   dual

如果NLS_TIMESTAMP_FORMAT 会话参数与您的格式模型'DD-MM-YYYY HH24:MI:SS' 不匹配,则会引发异常。

您可以更改NLS_TIMESTAMP_FORMAT 参数 - 但这是每个用户设置的会话参数,每个用户都可以在会话期间随时更改它,因此这应该不成为解决方案。

相反,您可以只使用 DATE 文字而不是 TIMESTAMP 文字:

SELECT DATE '1970-01-01' + NUMTODSINTERVAL (1511421211, 'second')
FROM   DUAL

或者,如果您想使用时间戳,那么您可以使用CAST 函数:

SELECT CAST(
         TIMESTAMP '1970-01-01 00:00:00' + NUMTODSINTERVAL (1511421211, 'second')
         AS DATE
       )
FROM   DUAL

【讨论】:

    【解决方案2】:

    这是你所期待的吗?

    select to_char(DATE '1970-01-01' + NUMTODSINTERVAL (1511421211, 'second'), 'yyyy/mm/dd hh24:mi:ss') from dual;
    

    【讨论】:

    • 这是我正在运行的查询并期望输出为 -- 选择 UNIX_TIMESTAMP(evt.event_time_stamp) 作为“---- 时间 ------------- ",来自 ap.ALTEREVT evt,其中 UNIX_TIMESTAMP(evt.event_time_stamp) > trunc(sysdate) - 间隔 '1' 天;预期输出:2017-12-11 11:50:54 2017-12-11 12:55:07 2017-12-12 10:07:04 2017-12-12 10:07:05
    • 我相信这篇文章可以帮助你。stackoverflow.com/questions/12105691/…
    • 我尝试了这个过程,但无法按预期获取值 create or replace FUNCTION unix_ts_to_date( p_unix_ts IN NUMBER ) RETURN DATE IS l_date DATE;开始 l_date := 日期 '1970-01-01' + p_unix_ts/60/60/24;返回 l_date;结束;
    • @arunb2w Oracle 日期始终包含时间戳。无需使用 to_char 进行转换即可显示时间戳。
    【解决方案3】:

    语法对我来说似乎有些不正确。试试这个:

    SELECT   TO_DATE ('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
           + NUMTODSINTERVAL (1511421211, 'second')
      FROM DUAL;
    

    编辑:

    正如@a_horse..所说“Oracle DATE 总是包含一个时间”,所以如果时间戳不可见,那么您只需要在表V$NLS_PARAMETERS 中查看您的NLS_DATE_FORMAT。在您的情况下,它只是设置为

    NLS_DATE_FORMAT = 'DD-MM-YYYY';

    因此,您需要先alter 会话才能在SQLPLUS 中获取timestamp。见下文:

    SQL> alter session set NLS_DATE_FORMAT = 'mm-dd-yyyy HH24:mi:ss';
    
    Session altered.
    
    SQL>   SELECT   TO_DATE ('1970-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + NUMTODSINTERVAL (15114212
    11, 'second')  FROM DUAL;
    
    TO_DATE('1970-01-01
    -------------------
    11-23-2017 07:13:31
    

    【讨论】:

    • OP 正在从另一个线程运行代码 - 请参阅我对这个问题的评论。
    • 可以进一步简化为DATE '1970-01-01' + NUMTODSINTERVAL (1511421211, 'second')
    • @a_horse_with_no_name 这也是正确的。 OP的原帖我没碰,只是重新整理了一下。
    • 如果你执行上面的查询,我们只得到日期而不是时间。
    • 我需要日期和时间
    猜你喜欢
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 2015-07-31
    • 1970-01-01
    相关资源
    最近更新 更多