이번 파트는 그레고리력에 기반한 오라클 DB의 날짜 관련 규칙에 한정해 설명한다.

SELECT TO_DATE('99991231', 'YYYYMMDD') + 1 FROM DUAL

위와 같이 날짜의 끝에서 + 1을 하면 ORA-01841 오류가 발생한다. 날짜의 범위를 넘어섰기 때문이다.

SELECT TO_DATE('00010101', ' YYYYMMDD') - 1 FROM DUAL

0001년 1월 1일에서 하루를 뺀 쿼리를 실행하면 0000년 12월 31일의 결과가 반환된다.

SELECT TO_DATE('00001231', 'YYYYMMDD') FROM DUAL

그러나 해당 날짜로 조회하면 없는 날짜라고 오류가 발생한다.

그레고리력에서는 1582년까지 누적된 역법상의 오차를 일괄 해소하고자 1582년10월5일에서 1582년10월14일 기간은 존재하지 않는 날로 지정했다.

SELECT TO_DATE('15821004', 'YYYYMMDD') + 1 FROM DUAL
====================
1582/10/15 00:00:00

1582년 10월 04일 다음날은 1582년 10월 15일이라고 조회된다. 10일의 기간이 사라진걸 알 수 있다.

SELECT TO_DATE('15821011', 'YYYYMMDD') FROM DUAL
====================
1582/10/15 00:00:00

사라진 기간 중 하루인 1582년 10월 11일 조회하면 1582년 10월 15일로 나타난다. 사라진 날짜는 모두 1582년 10월 15일로 인식된다.

그레고리력에서 윤년은 다음과 같다

  • 연도가 4년으로 나뉘어진다.
  • 1582년 이후에 100년으로 나누어 떨어지면 평년이다
  • 1582년 이후에 400년으로 나누어 떨어지면 윤년이다

쿼리로 작성하면 다음과 같이 작성할 수 있다.

SELECT DECODE(CASE WHEN MOD(연도, 4) = 0 THEN 1 ELSE 0 END
             + CASE WHEN MOD(연도, 100) = 0 AND 연도 > '1582' THEN -1 ELSE 0 END
             + CASE WHEN MOD(연도, 400) = 0 AND 연도 > '1582' THEN 1 ELSE 0 END,
             1, 'Y', 'N') AS 윤년
  FROM (SELECT '2016' AS 연도 FROM DUAL) -- 입력 값