Тъй като извършвате ненужно явно преобразуване от низ към дата, което прави имплицитно преобразуване от дата в низ въз основа на вашите 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
Забележете различните години в последните две стойности. Документацията има раздел за съвпадение на модел на формат
. Низът, който имплицитно създавате в средата, има 2-цифрена година. Когато конвертирате низа '30-APR-17'
обратно към дата с помощта на YY
модел, той „услужливо“ приема текущия век, така че датата завършва като 2017 г. Но когато конвертирате същия низ с помощта на YYYY
model смята, че наистина сте имали предвид стойността, която сте предали, и така не приема век - и сте го преминали 17, така че завършвате с година 17; тоест 0017, а не 2017. (Също така бихте получили отговора, който очаквахте, като използвате RRRR
, но е много по-добре да се придържате към YYYY
и всъщност използват 4-цифрени години навсякъде - ако всъщност изобщо трябва да използвате низ.)
По същество:не разчитайте на настройките на NLS или имплицитни преобразувания на дати в низове или обратно.
В този случай нямате нужда от никакви реализации, така че използвайте по-простото изявление в началото на този отговор.