Ponieważ robisz niepotrzebną jawną konwersję z ciągu na datę, co jest niejawnym konwersja z daty na ciąg na podstawie ustawień NLS.
To, co powinieneś zrobić, to po prostu:
select to_char(sysdate - 7, 'year') from dual;
TO_CHAR(SYSDATE-7,'YEAR')
------------------------------------------
twenty seventeen
Ponieważ sysdate-7
jest już datą, nie powinieneś wywoływać to_date()
wokół tego, w dowolnym formacie. Jako to_date()
funkcja przyjmuje argument w postaci łańcucha, twój sysdate-7
wyrażenie musi być najpierw niejawnie przekonwertowane na ciąg. Więc naprawdę robisz:
select to_char(to_date(to_char(sysdate - 7), 'DD/MM/YYYY'), 'year') from dual;
który używa Twojej wartości NLS_DATE_FORMAT dla niejawnej wewnętrznej to_char()
zadzwoń, więc jeśli to jest powiedz 'DD-MON-RR'
faktycznie robisz:
select to_char(to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY'), 'year') from dual;
Aby zobaczyć, co się tam dzieje, musisz zobaczyć, jaka jest pełna wygenerowana data, więc w tym celu zmienię NLS_DATE_FORMAT, aby sesja pokazywała cały rok:
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
Zwróć uwagę na różne lata w ostatnich dwóch wartościach. Dokumentacja zawiera sekcję dotyczącą dopasowywania modeli formatu
. Ciąg, który tworzysz niejawnie w środku, ma 2-cyfrowy rok. Po przekonwertowaniu ciągu '30-APR-17'
powrót do daty za pomocą YY
model, „pomocnie” zakłada bieżący wiek, więc data kończy się na 2017 r. Ale kiedy przekonwertujesz ten sam ciąg za pomocą YYYY
model myśli, że naprawdę miałeś na myśli wartość, którą przekazałeś, więc nie zakłada wieku - i zdałeś go 17, więc otrzymujesz rok 17; to znaczy 0017, a nie 2017. (Otrzymałbyś również oczekiwaną odpowiedź, używając YYYY
, ale znacznie lepiej jest trzymać się YYYY
i faktycznie wszędzie używamy 4-cyfrowych lat – jeśli faktycznie musisz w ogóle użyć ciągu znaków).
Zasadniczo:nie polegaj na ustawieniach NLS ani niejawnych konwersji dat na ciągi i odwrotnie.
W takim przypadku nie potrzebujesz żadnych konwersji, więc użyj prostszej instrukcji na górze tej odpowiedzi.