날짜 값 변수 계산
ABAP의 날짜 변수에 +, - 연산자를 사용하면 20260800처럼 잘못된 값이 만들어진다고 생각하기 쉽다.
하지만 변수가 실제 ABAP 날짜 타입인 TYPE d라면 별도의 Function Module 없이도 달력 기준 날짜 계산이 가능하다.
주의 아래 계산은 실제 기술 타입이 d인 변수에 해당한다. CHAR, NUMC, STRING 등에 YYYYMMDD 형식의 값이 들어 있다고 해서 날짜 계산이 적용되는 것은 아니다.
결론
결론부터 말하겠다.
Function Module을 호출하지 않아도 TYPE d 변수에서는 +, - 연산자를 이용해 날짜를 계산할 수 있다.
가장 권장하는 작성 방식은 다음과 같다.
DATA(lv_date) = CONV d( ls_header-pm_date ). " ls_header-pm_date TYPE d가 아닌 문자형 TYPE일때
lv_date -= 1.이 방식은 월 변경, 연도 변경, 윤년을 포함한 달력 기준 날짜 계산을 처리한다.
다만 영업일이나 공휴일을 기준으로 날짜를 계산해야 한다면 단순 산술 연산만으로는 부족하며, 팩토리 캘린더 관련 기능을 별도로 사용해야 한다.
기본적인 날짜 계산
다음과 같이 오늘 날짜를 선언했다고 가정한다.
DATA(lv_date) = sy-datum.SY-DATUM의 타입은 d이므로 인라인으로 선언한 LV_DATE 역시 d 타입이 된다.
LV_DATE 값이 20260804인 상태에서 하루를 빼면 다음과 같다.
lv_date = lv_date - 1.또는 축약형 연산자를 사용할 수 있다.
lv_date -= 1.결과: 20260804 → 20260803
이 경우에는 숫자에서 단순히 1을 빼더라도 같은 결과가 나오기 때문에 날짜 계산과 숫자 계산의 차이가 눈에 띄지 않는다.
하지만 월의 첫날에서 하루를 빼면 차이가 명확하게 나타난다.
DATA lv_date TYPE d.
lv_date = '20260801'.
lv_date -= 1.결과: 20260801 → 20260731
20260800이 되는 것이 아니라 달력 기준으로 이전 달의 마지막 날짜인 20260731이 된다.
날짜를 더할 때도 동일하다.
윤년 계산
TYPE d 날짜 계산은 윤년도 반영한다.
DATA lv_date TYPE d.
lv_date = '20240301'.
lv_date -= 1.결과: 20240301 → 20240229
2024년은 윤년이므로 3월 1일의 전날은 2월 29일이 된다.
문자형 날짜를 계산할 때
OData 요청값이나 JSON 데이터에서 받은 날짜는 CHAR, NUMC, STRING 타입일 수 있다.
이런 값을 바로 계산하면 정상적인 날짜 연산이 되지 않는다.
DATA lv_date_text TYPE c LENGTH 8.
lv_date_text = '20260801'.
lv_date_text = lv_date_text - 1.이 경우 값이 날짜가 아닌 숫자처럼 처리되어 다음과 같은 잘못된 결과가 발생할 수 있다.
20260801 → 20260800따라서 먼저 실제 날짜 타입인 d로 변환한 후 계산해야 한다.
DATA(lv_date) = CONV d( ls_header-pm_date ).
lv_date -= 1.결과: 20260801 → 20260731
인라인 선언 시 주의사항
DATA(lv_date) = CONV d( ls_header-pm_date ) - 1.오른쪽 전체가 산술식이기 때문에 LV_DATE의 타입은 d가 아니라 산술식의 계산 타입인 i로 추론될 수 있다.
따라서 날짜 변환과 계산을 분리하는 것이 가장 명확하다.
DATA(lv_date) = CONV d( ls_header-pm_date ).
lv_date -= 1.또는 타입 Conversion을 두번 실행해야한다.
DATA(lv_date) = CONV d( CONV d( ls_header-pm_date ) - 1 ).