Функций для работы с датами к сожалению в системе написано много, ощущение, что каждый индус (как каждый хомячок, которому в жизни требуется нажраться и сдохнуть) должен был при возникновении потребности в расчете даты писать свою реализацию. Может это было бы и неплохо, если бы не одно, но... некоторые функции учитывают рабочий календарь, другие нет... третьи вообще не знают что есть высокосные года (может в Индии их просто нет), четвертые просто содержать ошибку при расчетах и т.д. В общем у кого есть свой наработанный материал по работе с датами и есть время поделится, пишем. Небольшая подборка которой пользуюсь:
* Возвращает номер недели для даты: в формате YYYYWW (YYYY - Год, WW - Неделя)
DATA: l_week LIKE scal-week.
CALL FUNCTION 'DATE_GET_WEEK'
EXPORTING
date = sy-datum
IMPORTING
week = l_week
EXCEPTIONS
date_invalid = 1
OTHERS = 2.
* Возвращает дату с которой начинается неделя по ее номеру.
* Номер недели в формате YYYYWW (YYYY - Год, WW - Неделя)
* Дата в стандартном формате типа SY-DATUM (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День)
DATA: l_week LIKE scal-week,
l_datum like sy-datum.
CALL FUNCTION 'WEEK_GET_FIRST_DAY'
EXPORTING
week = l_week
IMPORTING
DATE = l_datum
EXCEPTIONS
WEEK_INVALID = 1
OTHERS = 2.
* Возвращает дату последнего дня в месяце, в принципе можно использовать так же
* для получения количества дней в месяце. О высокосном годе знает ;)
* Дата передается и возвращается в стандартном формате типа SY-DATUM (YYYYMMDD,
* YYYY - Год, MM - Месяц, DD - День)
DATA: l_datum LIKE sy-datum.
CALL FUNCTION 'RP_LAST_DAY_OF_MONTHS'
EXPORTING
day_in = sy-datum
IMPORTING
last_day_of_month = l_datum
EXCEPTIONS
day_in_no_date = 1
OTHERS = 2.
* Выполняет преобразование внутреннего представления даты в стандартный вид
* типа SY-DATUM. Я знаю только одну ситуацию, где используется такое, это таблица
* курсов валют TCURR, там все даты заданы именно во внутреннем формате.
* Передается дата в формате вида TCURR-GDATU, а возвращается стандартное
* представление типа SY-DATUM (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День)
DATA: l_datum LIKE sy-datum,
l_gdatu LIKE tcurr-gdatu.
l_gdatu = '79948998'.
CALL FUNCTION 'DATE_CONV_EXT_TO_INT'
EXPORTING
i_date_ext = l_gdatu
IMPORTING
e_date_int = l_datum
EXCEPTIONS
error = 1
OTHERS = 2.
* Получить дату начала периода к варианту финансового года. Стандартные параметры
* Год вида YYYY. Вариант финансового года для БЕ в виде CC. Номер требуемого периода
* задается в формате NNN Возвращаемая дата представлена в стандартном типе SY-DATUM
* (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День)
* Стандартно как бы используется практически везде вариант финансового года K4 - т.е.
* 4 квартала, однако знавал я систему, где были настроены свои периоды. Так что если
* пишем универсальную программу, то начало периода лучше считать используя данный ФМ
DATA: l_gjahr LIKE t009b-bdatj,
l_periv LIKE t009b-periv,
l_poper LIKE t009b-poper,
l_datum LIKE sy-datum.
l_gjahr = '2007'.
l_periv = 'K4'.
l_poper = '002'.
CALL FUNCTION 'FIRST_DAY_IN_PERIOD_GET'
EXPORTING
i_gjahr = l_gjahr
* I_MONMIT = 00
i_periv = l_periv
i_poper = l_poper
IMPORTING
e_date = l_datum
EXCEPTIONS
input_false = 1
t009_notfound = 2
t009b_notfound = 3
OTHERS = 4.
* Получить дату конца периода к варианту финансового года. Стандартные параметры
* Год вида YYYY. Вариант финансового года для БЕ в виде CC. Номер требуемого периода
* задается в формате NNN Возвращаемая дата представлена в стандартном типе SY-DATUM
* (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День)
* Собственно причина почему ее желательно использовать такая же как и для предыдущего
* функционального модуля FIRST_DAY_IN_PERIOD_GET.
DATA: l_gjahr LIKE t009b-bdatj,
l_periv LIKE t009b-periv,
l_poper LIKE t009b-poper,
l_datum LIKE sy-datum.
l_gjahr = '2007'.
l_periv = 'K4'.
l_poper = '002'.
CALL FUNCTION 'LAST_DAY_IN_PERIOD_GET'
EXPORTING
i_gjahr = l_gjahr
* I_MONMIT = 00
i_periv = l_periv
i_poper = l_poper
IMPORTING
e_date = l_datum
EXCEPTIONS
input_false = 1
t009_notfound = 2
t009b_notfound = 3
OTHERS = 4.
* Позволяет узнать какая будет дата через NN-Дней, MM-Месяцев и YY-Лет от заданной.
* При этом можно как суммировать так и отнимать требуемое количество дней, месяцев и
* лет. О высокосном годе вроде как тоже знает. Из полезного можно добавлять например 55
* дней и 1 месяц и т.д. Если даты нужно отнимать, тогда нужно задать параметр SIGNUM = '-'
DATA: l_days LIKE t5a4a-dlydy,
l_months LIKE t5a4a-dlymo,
l_years LIKE t5a4a-dlyyr,
l_datum LIKE sy-datum.
l_days = '10'.
l_month = '05'.
l_years = '02'
call function 'RP_CALC_DATE_IN_INTERVAL'
exporting
date = sy-datum
days = l_days
months = l_months
signum = '+'
years = l_years
importing
calc_date = l_datum.
* В данном вызове для даты 01.02.2007 будет возвращена дата 11.07.2009.
* Высчитывает разницу в днях и часах между двумя произвольно заданными датами
* Дата и время начала и конца диапазона задаются в стандартном типе SY-DATUM
* (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День).
* Из особенностей работы:
* 1. Разница вычисляется только для полного количества часов, т.е. между 01:00 и 02:30
* будет возвращено все равно 1 час.
* 2. Обязательно нужно задавать поля времени, например хотя бы 1 минута, иначе функция
* ничего не вернет (Спасибо индусам за наше счастливое детство, но оказывается в этой
* Индии 00:00:00 времени не бывает в принципе)
* 3. Даты можно задавать как от большей к меньшей так и наоборот, при этом переменная l_earliest
* будет содержать следующие значения =2 - дата1 больше даты2, =1 - дата1 меньше дата2, если даты
* равны, тогда сравниваются времена и =2 - время1 больше времени2 и =1 - время 1 меньше времени2,
* если даты и время совпадают, тогда переменная = 0.
DATA: l_datum_one LIKE sy-datum,
l_time_one LIKE sy-uzeit,
l_datum_two LIKE sy-datum,
l_time_two LIKE sy-uzeit.
DATA: l_datediff TYPE p,
l_timediff TYPE p,
l_earliest TYPE c.
CALL FUNCTION 'SD_DATETIME_DIFFERENCE'
EXPORTING
date1 = l_datum_one
time1 = l_time_on
date2 = l_datum_two
time2 = l_time_two
IMPORTING
datediff = l_datediff
timediff = l_timediff
earliest = l_earliest
EXCEPTIONS
invalid_datetime = 1
OTHERS = 2.
* Возвращает внутренню таблицу со списком как сокращенных наименований месяцев
* (3 символа), так и полных в именительном падеже на заданном языке. По умолчанию
* используется язык регистрации в системе.
DATA: l_retcode LIKE like sy-subrc,
lt_month LIKE t247 OCCURS 1 WITH HEADER LINE.
CALL FUNCTION 'MONTH_NAMES_GET'
EXPORTING
language = sy-langu
IMPORTING
return_code = l_retcode
TABLES
month_names = lt_month
EXCEPTIONS
month_names_not_found = 1
OTHERS = 2.
* Для языка RU таблица lt_month, будет содержать что-то типа такого:
* SP MN KTX LTX
* -------------
* RU 01 ЯНВ Январь
* RU 02 ФЕВ Февраль
* RU 03 МАР Март
* RU 04 АПР Апрель
* RU 05 МАЙ Май
* RU 06 ИЮН Июнь
* RU 07 ИЮЛ Июль
* RU 08 АВГ Август
* RU 09 СЕН Сентябрь
* RU 10 ОКТ Октябрь
* RU 11 НОЯ Ноябрь
* RU 12 ДЕК Декабрь
* Возвращает в заданном диапазоне список выходных/праздничных дней для выбранного
* производственного и праздничного календаря. Праздничные и выходные дни берутся из
* настройки соответствующих календарей, так что если там пусто, то и список будет пустой.
* Если заданные календари не найдены тогда l_returncode = '4'.
DATA: l_holiday_calendar LIKE scal-hcalid,
l_factory_calendar LIKE scal-fcalid,
l_date_from LIKE scal-date,
l_date_to LIKE scal-date,
l_year_of_valid_from LIKE scal-year,
l_year_of_valid_to LIKE scal-year,
l_returncode LIKE sy-subrc,
lt_holidays LIKE iscal_day OCCURS 1 WITH HEADER LINE.
l_factory_calendar = 'UA'.
l_holiday_calendar = 'UA'
l_date_from = '18.07.2007'.
l_date_to = '18.07.2007'.
CALL FUNCTION 'HOLIDAY_GET'
EXPORTING
holiday_calendar = l_holiday_calendar
factory_calendar = l_factory_calendar
date_from = l_date_from
date_to = l_date_to
IMPORTING
year_of_valid_from = l_year_of_valid_from
year_of_valid_to = l_year_of_valid_to
returncode = l_returncode
TABLES
holidays = lt_holidays
EXCEPTIONS
factory_calendar_not_found = 1
holiday_calendar_not_found = 2
date_has_invalid_format = 3
date_inconsistency = 4
OTHERS = 5.
* Формат вывода таблички lt_holidays, для приведенного пример следующий:
* DATE F H HOL TXT_SHORT TXT_LONG
* ----------------------------------------
* 28.06.2007 X X 168 День конст День конституції
* 24.08.2007 X X 169 День Незал День Незалежності
* 01.01.2008 X X 171 Новий Рік Новий Рік
* 07.01.2008 X X 172 Різдво Хри Різдво Христово
* 01.05.2008 X X 163 1 Травня 1 Травня
* 02.05.2008 X X 164 2 Травня 2 Травня
* 09.05.2008 X X 170 День Перем День Перемоги