Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

The Problem

I was working on a project that required me to calculate a date three months in the future and then take the last day of the month. Pretty simple huh? Do something like:

The above example produces:


Using FM RP_CALC_DATE_IN_INTERVAL                                
15.09.2010 - end of the month 3 months in the future -> 31.12.2010


This appears correct to me.


Changing old_dt to ‘20100901’ produces the same results, as does ‘20100930’.
So for any date in September, we get the results we expect.

Now, try it with ‘20107015’. You should see:

Using FM RP_CALC_DATE_IN_INTERVAL                                
15.07.2010 - end of the month 3 months in the future -> 31.10.2010


Using ‘20100701’ gives the same results. But what happens if you use ‘20100731’?
Remarkably, you get:

Using FM RP_CALC_DATE_IN_INTERVAL                                
31.07.2010 - end of the month 3 months in the future -> 30.11.2010


This is because when the function module is asked to calculate a date X months in the future and the day of the starting date is greater than the end day of the month that it would normally calculate, instead of returning the end of that month it returns the first day of the following month. Well, you might say that this is what you want. On the other hand, in the project I was working on, it was not.


Consider a completely different case. Suppose you want to add some months to a date and also some days. RP_CALC_DATE_IN_INTERVAL can do this. It has parameters for days, months and years and you can tell it whether you want to go forward or backward. But before looking at how the FM would do this, let’s work through an example. Let’s say your starting date is ‘20100930’ and you want to add one month and one day to it:


‘20100930’ plus 1 day gives ‘20101001’. Adding one month to that gives ‘20101101’.


But let’s do it the other way:


‘20100930’ plus 1 month gives ‘20101030’. Adding one day to that gives ‘20101031’.


So even without using any ABAP function module, you can see that the results of date calculations are not necessarily deterministic. That’s not to say they are incorrect, just that you can’t say for sure what you are going to get.


This is because although we can use numbers to represent dates, these numerical representations are not real numbers. I mean “real numbers” in the mathematical sense that they do not obey the associative law: A + B + C does not necessarily equal A + C + B.


So what does this mean?


First of all, this should not be a big problem. It will only crop up when doing calculations around the ends of certain months. But programming needs to be done accurately and must accommodate all cases; otherwise, you get angry calls from impatient users. So we should not blindly plug dates and numbers into ABAP and expect the results to be what you and your users want. You have to look at the requirements or specifications and determine exactly what they imply. This may mean that you have to go back to the user, explain the problem and get clarification. But in the end, we live in the real world and we will have to calculate dates that are days months and/or years in the future (or past).

We can start by not using function modules that try to do the additions of different units such as RP_CALC_DATE_IN_INTERVAL. (There are others as well.) I think a better approach is to use the methods of class cl_hrpt_date_tools. They allow only one operation at a time and they also give better results than RP_CALC_DATE_IN_INTERVAL for the first case I showed. If you do:

 

You will at least get:


Using method add_date                                            
31.07.2010 - end of the month 3 months in the future -> 31.10.2010


To me, this is the correct answer.

Another thing to bear in mind is that function module RP_CALC_DATE_IN_INTERVAL (and its clones) are neither documented nor released. So caveat emptor.

But whatever method you choose, test to make sure the results are what you want.

9 Comments