Often, a seemingly small and simple task is actually a little bigger, the more and deeper you think of it, you sure have experienced this as well. Here’s an example:
Task: Select something from the last 24 hours (e.g. sales orders (VBAK) maybe to see the turnover in $ in the last 24h hours, or how many units of Product X have been produced per plant )
So, we need to calculate the “target” date and time -> 24 hours in the past.
data(lv_target_date) = sy-datum - 1. data(lv_target_time) = sy-uzeit.
But we probably want 24hours back from the users “definition of now“, not from the system-time (yeah, they might be different, if user and server are in different timezones), so better use sy-datlo + sy-timlo:
data(lv_target_date) = sy-datlo - 1. data(lv_target_time) = sy-timlo.
Now the following was not explicitly stated, but implicitly it is: If “today” is a Monday, we would want to look back as far as Friday (’cause there’s not turnover/production/… at the weekend – well, unless we have online sales, but that’s another story.)
So, things are clear: we have to take the factory calendar into account.
SELECT SINGLE fabkl FROM t001w INTO data(lv_factory_calendar) WHERE werks = iv_werks. *if there is no factory calendar, we're fine with what we already calculated! CHECK sy-subrc EQ 0. CHECK lv_factory_calendar IS NOT INITIAL. CALL FUNCTION 'DATE_CONVERT_TO_FACTORYDATE' EXPORTING correct_option = '-' date = lv_target_date factory_calendar_id = lv_factory_calendar IMPORTING date = lv_target_date * factorydate = * workingday_indicator = EXCEPTIONS calendar_buffer_not_loadable = 1 correct_option_invalid = 2 date_after_range = 3 date_before_range = 4 date_invalid = 5 factory_calendar_not_found = 6 OTHERS = 7. IF sy-subrc <> 0. *doesn't matter. ENDIF.
What does it do: if what we calculated as lv_target_day in the first step is NOT a working day, go as far back, until you hit a working day.
That’s what I wanted to say about the date part, but I also have one for the time:
If it’s March, 28th (this year, 2018), 8 O’clock in the morning, what’s the target if we go 24h back? Well: March, 27th, 7 O’clock in the morning! That’s right, at least if we are in a timezone which switched to daylight-saving-time: the hour between 2 and 3 didn’t exist that night!
I have no solution to that, I think this can or at least should not be coded by hand. I would hope + guess that there’s a library somewhere, which takes care of exactly those things I mentioned here. If you know it, please share in the comments.
Let me end with a nice blog I read a few years ago and now went searching for again:
( If you like it, you probably like this one about names as well:
Also, to link to a currently trending topic: you probably can and should write #unit-tests for those edge-cases displayed here.
Over to you:
– Do you see other problems not yet addressed here?
– Do you know the library (e.g. ABAP-Class) that helps me with all the time-handling
– I guess there should be a more modern way (ABAP-Class) for “CALL FUNCTION ‘DATE_CONVERT_TO_FACTORYDATE'” , do you know it?
– would you have fallen for one of the ‘traps’ I mentioned here, where they all obvious to you?
This and other input is most welcome!