文字列から日付への不必要な明示的な変換を行っているため、暗黙的 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;
暗黙の内部 to_char()
に NLS_DATE_FORMAT 値を使用しています 呼び出すので、それが '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 つの値の異なる年に注意してください。 ドキュメントには、フォーマット モデルの一致に関するセクションがあります
.中間で暗黙的に作成している文字列には、2 桁の年があります。文字列 '30-APR-17'
を変換すると YY
を使用して日付に戻る モデルでは、現在の世紀を「参考に」想定しているため、日付は 2017 になります。しかし、YYYY
を使用して同じ文字列を変換すると、 モデルは、あなたが渡した値を本当に意味していると考えているため、1世紀を想定していません.17を渡したので、17年になります。つまり、2017 ではなく 0017 です。 、しかし YYYY
に固執する方がはるかに良い 実際にはどこでも 4 桁の年を使用します - if 実際には文字列を使用する必要があります。)
基本的に:NLS 設定や日付から文字列への暗黙的な変換、またはその逆に依存しないでください。
この場合、何も必要ありません コンバージョンなので、この回答の上部にあるより単純なステートメントを使用してください。