Oracle
 sql >> Database >  >> RDS >> Oracle

TO_DATE yy,yyyy mi dà risultati diversi

Perché stai eseguendo una conversione esplicita non necessaria da stringa a data, che sta facendo un implicito conversione da data a stringa in base alle tue impostazioni NLS.

Quello che dovresti fare è solo:

select to_char(sysdate - 7, 'year') from dual;

TO_CHAR(SYSDATE-7,'YEAR')                 
------------------------------------------
twenty seventeen

Perché sysdate-7 è già una data, non dovresti chiamare to_date() intorno a questo, con qualsiasi formato. Come to_date() la funzione accetta un argomento stringa, il tuo sysdate-7 l'espressione deve essere prima convertita in modo implicito in una stringa. Quindi stai davvero facendo:

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

che sta usando il tuo valore NLS_DATE_FORMAT per l'implicito interno to_char() chiama, quindi se è dire 'DD-MON-RR' stai effettivamente facendo:

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

Per vedere cosa sta succedendo lì dentro devi vedere qual è la data di generazione completa, quindi per questo cambierò NLS_DATE_FORMAT per la sessione per mostrare l'intero anno:

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

Notare i diversi anni negli ultimi due valori. La documentazione ha una sezione sulla corrispondenza del modello di formato . La stringa che stai creando implicitamente nel mezzo ha un anno a 2 cifre. Quando converti la stringa '30-APR-17' torna a una data utilizzando un YY modello, "utile" presuppone il secolo corrente, quindi la data finisce nel 2017. Ma quando converti la stessa stringa usando un YYYY modello pensa che tu intendessi davvero il valore in cui sei passato e quindi non presuppone un secolo - e lo hai superato 17, quindi finisci con l'anno 17; cioè 0017 e non 2017. (Avresti anche ottenuto la risposta che ti aspettavi usando RRRR , ma è molto meglio attenersi a YYYY e in realtà usa anni a 4 cifre ovunque - se in realtà è necessario utilizzare una stringa.)

In sostanza:non fare affidamento su impostazioni NLS o conversioni implicite di date in stringhe o viceversa.

In questo caso non è necessario nessuno conversioni, quindi usa l'istruzione più semplice all'inizio di questa risposta.