oracle에서 add_months 함수로 날짜를 구했었다.
대부분의 날짜들은 상관 없지만 말일(30,31)의 한달 후가 문제였었다.
2023.09.30의 한달 뒤면 2023.10.30 이고
2023.10.31의 한달 뒤면 2023.12.01 이 되길 원했었는데(만근을 구해야해서)
실제로 나온 값은
SELECT ADD_MONTHS(TO_DATE(20231031, 'YYYYMMDD'), 1) DD
FROM DUAL
-- 2023-10-31 00:00:00.000
SELECT ADD_MONTHS(TO_DATE(20231031, 'YYYYMMDD'), 1) DD
FROM DUAL;
-- 2023-11-30 00:00:00.000
그래서
SELECT
CASE
/* 20230920 */
WHEN LAST_DAY(BASE_DATE) != BASE_DATE
THEN ADD_MONTHS(BASE_DATE, 1) /* 20231020 */
/* 20230930 */
WHEN LAST_DAY(BASE_DATE) = BASE_DATE AND TO_CHAR(BASE_DATE, 'DD') = '30'
THEN ADD_MONTHS(BASE_DATE, 1) - 1 /* 20231030 */
/* 20231031 */
WHEN LAST_DAY(BASE_DATE) = BASE_DATE AND TO_CHAR(BASE_DATE, 'DD') = '31'
THEN ADD_MONTHS(BASE_DATE, 1) + 1 /* 20231201 */
ELSE ADD_MONTHS(BASE_DATE, 1)
END DD
FROM DUAL;
SELECT
CASE
/* 기준일이 말일(마지막날)이 아닐 때 */
WHEN LAST_DAY(기준일) != 기준일
THEN ADD_MONTHS(기준일, 1)
/* 기준일이 말일이면서 30일 때 */
WHEN LAST_DAY(기준일) = 기준일 AND TO_CHAR(기준일, 'DD') = '30'
THEN ADD_MONTHS(기준일, 1) - 1
/* 기준일이 말일이면서 31일 때 */
WHEN LAST_DAY(기준일) = 기준일 AND TO_CHAR(기준일, 'DD') = '31'
THEN ADD_MONTHS(기준일, 1) + 1
ELSE ADD_MONTHS(기준일, 1)
END DD
FROM DUAL;
-- 최종
SELECT
CASE
/* 0129, 0130, 0131 모두 한달 뒤가 0228 로 나와서 이렇게 처리함 */
WHEN TO_CHAR(BASE_DATE, 'MMDD') IN ('0129', '0130', '0131')
THEN TO_DATE(TO_CHAR(BASE_DATE, 'YYYY') || '0301', 'YYYYMMDD')
/* 20230920 */
WHEN LAST_DAY(BASE_DATE) != BASE_DATE
THEN ADD_MONTHS(BASE_DATE, 1) /* 20231020 */
/* 20230930 */
WHEN LAST_DAY(BASE_DATE) = BASE_DATE AND TO_CHAR(BASE_DATE, 'DD') = '30'
THEN ADD_MONTHS(BASE_DATE, 1) - 1 /* 20231030 */
/* 0228, 0229, 0031은 여기서 처리 */
WHEN LAST_DAY(BASE_DATE) = BASE_DATE AND TO_CHAR(BASE_DATE, 'DD') != '30'
THEN ADD_MONTHS(BASE_DATE, 1) + 1
ELSE ADD_MONTHS(BASE_DATE, 1)
END DD
FROM DUAL;
이렇게 작성한 이유: 한달 만근한 다음날을 구하기 위해서
1.28, 1.29, 1.30, 1.31들의 한달 만근한 다음날은 3.1이 된다.
9.30의 다음 만근 기준일들은 10.30, 11.30, 12.30, 1.30, 03.01 ... 이다.
10.31의 다음 만근 기준일들은 12.01, 01.01, 02.01 ... 이다.
INTERVAL 대신에 ADD_MONTHS 를 쓴 이유: 1월 31일의 한달 뒤를 구할 경우 오류 발생
SELECT TO_DATE(20230131, 'YYYYMMDD') + INTERVAL '1' MONTH
FROM DUAL
-- SQL Error ORA-01839: 지정된 월에 대한 날짜가 부적합합니다
인터넷 안 되는 곳에서 일하니 답답하다.
까먹을까봐 집에 와서 적어본다.