SAP ABAP: Date Calculations

As you might see in different ABAP forums people ask repeatedly for a function module doing some simple date calculation, e.g. end of month or weekday calculation. The first question, the rhetorical one - "why on earth they cannot search the SAP repository themselves" - definitely has no answer. We must assume that there is a kind of people whose mentality prevents them from trying to solve problems themselves; they always seek help from others in their everyday duties.
The other question is why at all one needs an FM for these particular calculations. Just think: ABAP has a special data type for dates, and it has built-in efficient date arithmetic, so why not to use it.  
For example, if you need to add a number of days to a date, you can use a simple ADD statement or arithmetic '+' operation, where one operand is of type d and the other is of type integer.
Another example is weekday calculation. Knowing that 01/01/1900 was Monday, you can always calculate a weekday by the simple statement:
CONSTANTS: c_known_monday TYPE d VALUE '19000101'. "It's Monday  weekday = ( given_Date - c_known_monday ) mod 7 + 1. 
The result will be the number of range from 1 to 7, where 1 is Monday and 7 is Sunday. This calculation will work also correctly for dates before 01/01/1900. You can use the result as a key for T246 SAP table, which stores weekday names in different languages.
A little harder is end-of-month calculation. By the way, you can find in SAP system repository several FMs calculating an end-of-month day, with more or less correct leap year calculation. However, the thing is that having built-in ABAP date arithmetic you hardly need an FM, and you don't need to calculate a leap year.
Suppose, you have a variable SOMEDATE with arbitrary date. First, we calculate the first day of a month (remember, internally date is represented in ABAP as YYYYMMDD):
SOMEDATE+6(2) = '01'.
Next, we have to find some date in the next month. Knowing the first day of the month, we can add, for example, 31 days to that day, and the result will obviously be in the next month boundaries:
ADD 31 TO SOMEDATE.
Next, let's again calculate the first day of the month (in this step this will be the next month):
SOMEDATE+6(2) = '01'.
Now as we have the first day of the next month we can just subtract 1 day, and the result will be our end-of-month day:
SUBTRACT 1 FROM SOMEDATE.
So, the calculation consists of just four statements:
SOMEDATE+6(2) = '01'. ADD 31 TO SOMEDATE. SOMEDATE+6(2) = '01'. SUBTRACT 1 FROM SOMEDATE. 
No IF's, no CASE's. The good idea is to encapsulate this code snippet into a parametric macro definition; no need for another function module as the cost of its call will be far beyond the payload.
Author: Sergey Korolev
Source: sdn. sap. com

1 comment:

  1. End of date calculation, your aldorithm is wrong.

    31.03.2010 + 31 is 01.05.2010! which will give 30.4.2010 as month-end-day for march

    ReplyDelete