【问题标题】:TO_DATE yy,yyyy gives me different resultsTO_DATE yy,yyyy 给了我不同的结果
【发布时间】:2017-10-05 04:30:34
【问题描述】:

如果我运行以下查询

select to_char(TO_DATE(SYSDATE-7,'DD/MM/YY') ,'year') from dual

结果是二十七

select to_char(TO_DATE(SYSDATE-7,'DD/MM/YYYY') ,'year') from dual

结果是十七

为什么第二个查询我没有得到二十七?

【问题讨论】:

    标签: plsql oracle11g


    【解决方案1】:

    因为您正在进行从字符串到日期的不必要的显式转换,即根据您的 NLS 设置从日期到字符串的隐式转换。

    你应该做的只是:

    select to_char(sysdate - 7, 'year') from dual;
    
    TO_CHAR(SYSDATE-7,'YEAR')                 
    ------------------------------------------
    twenty seventeen
    

    因为sysdate-7 已经是一个日期,所以您不应该以任何格式调用to_date()。由于to_date() 函数采用字符串参数,因此您的sysdate-7 表达式必须首先隐式转换为字符串。所以你真的在做:

    select to_char(to_date(to_char(sysdate - 7), 'DD/MM/YYYY'), 'year') from dual;
    

    将您的 NLS_DATE_FORMAT 值用于隐式内部 to_char() 调用,所以如果说 'DD-MON-RR' 您实际上是在做:

    select to_char(to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY'), 'year') from dual;
    

    要查看其中发生的情况,您需要查看生成的完整日期,因此我将更改会话的 NLS_DATE_FORMAT 以显示全年:

    alter session set nls_date_format = 'SYYYY-MM-DD';
    
    select sysdate - 7 as raw_date,
      to_char(sysdate - 7, 'DD-MON-RR') as implicit_string,
      to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YY') as implcit_yy,
      to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY') as implcit_yyyy
    from dual;
    
    RAW_DATE    IMPLICIT_STRING    IMPLCIT_YY  IMPLCIT_YYY
    ----------- ------------------ ----------- -----------
     2017-04-30 30-APR-17           2017-04-30  0017-04-30
    

    注意最后两个值中的不同年份。 The documentation has a section on format model matching。您在中间隐式创建的字符串具有 2 位数的年份。当您使用YY 模型将字符串'30-APR-17' 转换回日期时,它“有帮助”假设当前世纪,因此日期最终为2017。但是当您使用YYYY 模型转换相同的字符串时认为你真的是指你传入的值,所以不假设一个世纪 - 你通过了 17 年,所以你最终得到了 17 年;即 0017 而不是 2017。(使用RRRR 也会得到预期的答案,但最好坚持使用YYYY 并实际在所有地方使用 4 位数年份 - if 你实际上需要使用一个字符串。)

    本质上:不要依赖 NLS 设置或日期到字符串的隐式转换,反之亦然。

    在这种情况下,您不需要 任何 转换,因此请使用此答案顶部的更简单的语句。

    【讨论】:

    • 感谢@Alex Poole 的解释。
    【解决方案2】:

    第二个查询应该是 2017,而不是第一个查询。其他可能性是 NLS 设置或会话、软件设置。 除此之外,您必须使用 'YYYY' 而不是 'YY' 才能获得 2017

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-30
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 2021-12-28
      • 2013-10-28
      相关资源
      最近更新 更多