В данной теме хочется поговорить о функциях работы с датами.
Очень часто в своих разработках мы используем данные функции п.э. далее перечислим самые популярные и полезные на мой взгляд.
Очень часто в своих разработках мы используем данные функции п.э. далее перечислим самые популярные и полезные на мой взгляд.
Даты передается и возвращается в стандартном формате типа SY-DATUM (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День):
data: begda like sy-datum,
endda like sy-datum.
Я думаю все знают как получить первый день месяца.
CONCATENATE YYYY MM '01' into begda.
* Возвращает последний день месяца в формате YYYYMMDD (YYYY - Год, MM - Месяц, DD - День).
* Определение номера недели для даты в формате YYYYWW (YYYY - Год, WW - Неделя):
* Возвращает дату, с которой начинается неделя по ее номеру. Номер недели в формате YYYYWW (YYYY - Год, WW - Неделя). Дата в стандартном формате типа SY-DATUM (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День):
* Преобразование внутреннего представления даты в стандартный вид типа SY-DATUM. Знаю только одну ситуацию, где используется такое, это таблица курсов валют TCURR, там все даты заданы именно во внутреннем формате. Передается дата в формате вида TCURR-GDATU, а возвращается стандартное представление типа SY-DATUM (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День):
* Дата начала периода к варианту финансового года. Стандартные параметры - год вида YYYY. Вариант финансового года для БЕ в виде CC. Номер требуемого периода задается в формате NNN. Возвращаемая дата представлена в стандартном типе SY-DATUM (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День). Стандартно как бы используется практически везде вариант финансового года K4 - т.е. 4 квартала. Если пишем универсальную программу, то начало периода лучше считать используя данный ФМ:
* Дата конца периода к варианту финансового года. Стандартные параметры - год вида YYYY. Вариант финансового года для БЕ в виде CC. Номер требуемого периода задается в формате NNN. Возвращаемая дата представлена в стандартном типе SY-DATUM (YYYYMMDD, YYYY - Год, MM - Месяц, DD - День). Собственно причина почему её желательно использовать такая же как и для предыдущего функционального модуля FIRST_DAY_IN_PERIOD_GET:
* Дата через NN-Дней, MM-Месяцев и YY-Лет от заданной. При этом можно как суммировать так и отнимать требуемое количество дней, месяцев и лет. О високосном годе, вроде, как тоже знает. Из полезного можно добавлять например 55 дней и 1 месяц и т.д. Если даты нужно отнимать, тогда нужно задать параметр SIGNUM = '-':
* Возвращает внутреннюю таблицу со списком, как сокращенных наименований месяцев (3 символа), так и полных, в именительном падеже на заданном языке. По умолчанию, используется язык регистрации в системе:
Так же есть еще одна хорошая функция попоиску имени месяца в именительном и родительном падеже:
* Возвращает в заданном диапазоне список выходных/праздничных дней для выбранного производственного и праздничного календаря. Праздничные и выходные дни берутся из настройки соответствующих календарей, так что если там пусто, то и список будет пустой. Если заданные календари не найдены тогда l_returncode = '4':
* Функция округления даты. В общем виде возвращает последний/первый день недели, месяца, года... иногда полезно, чтобы не вызвать кучу функций расчета даты:
* Выдает текстовое имя дня недели и полную строку дня. Возвращает таблицу дней, так что можно задать диапазон дат:
* Возвращает кол-во лет, месяцев, дней между 2-мя датами.
Для точности отнять от даты окончания один день
t_date = t_date - 1.
CALL FUNCTION 'HR_HK_DIFF_BT_2_DATES'
EXPORTING
date1 = t_date
date2 = t_dat01
output_format = '05'
IMPORTING
years = years
months = months
days = days
EXCEPTIONS
invalid_dates_specified = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
endda like sy-datum.
Я думаю все знают как получить первый день месяца.
CONCATENATE YYYY MM '01' into begda.
* Возвращает последний день месяца в формате YYYYMMDD (YYYY - Год, MM - Месяц, DD - День).
CALL FUNCTION 'LAST_DAY_OF_MONTHS'EXPORTING
DAY_IN = begda
IMPORTING
LAST_DAY_OF_MONTH = endda
EXCEPTIONS
DAY_IN_NO_DATE = 1
OTHERS = 2.
* Определение номера недели для даты в формате 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. Знаю только одну ситуацию, где используется такое, это таблица курсов валют 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 - День). Из особенностей работы:
- Разница вычисляется только для полного количества часов, т.е. между 01:00 и 02:30 будет возвращено все равно 1 час.
- Обязательно нужно задавать поля времени, например хотя бы 1 минута, иначе функция ничего не вернет (Спасибо индусам за наше счастливое детство, но оказывается в этой Индии 00:00:00 времени не бывает в принципе).
- Даты можно задавать как от большей к меньшей так и наоборот, при этом переменная 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.
Так же есть еще одна хорошая функция попоиску имени месяца в именительном и родительном падеже:
DATA: period(2) TYPE n, month_name(25) type c. CALL FUNCTION 'HR_PAY_UA_MONTH_NAME' EXPORTING MONTHNUM = period IMPORTING MN_NOM = month_name.
* Возвращает в заданном диапазоне список выходных/праздничных дней для выбранного производственного и праздничного календаря. Праздничные и выходные дни берутся из настройки соответствующих календарей, так что если там пусто, то и список будет пустой. Если заданные календари не найдены тогда 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 | День Перем | День Перемоги |
* Позволяет получить информацию о статусе рабочего дня исходя из данных производственного календаря, присвоенного заводу. При этом, если день не является рабочим, то функция вернет следующий рабочий день в зависимости от параметров.
CORRECT_OPTION | = '+' - Будет возвращен следующий рабочий день = '-' - Будет возвращен предыдущий рабочий день |
DATE | = Дата которую требуется проверить |
FACTORY_CALENDAR_ID | = Код производственного календаря из T001W |
DATA: l_date LIKE scal-date, l_factorydate LIKE scal-facdate, l_workingday_indicator LIKE scal-indicator. CALL FUNCTION 'DATE_CONVERT_TO_FACTORYDATE' EXPORTING correct_option = '+' date = sy-datum factory_calendar_id = 'RU' IMPORTING date = l_date factorydate = l_factorydate workingday_indicator = l_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.
Результат:
DATE | = Дата формата SY-DATUM |
FACTORYDATE | = Дата во внутреннем формате виде TCURR-GDATU, полезно для чтения курса валюты например. |
WORKINGDAY_INDICATOR |
= В принципе в нем возвращается значение, которое передается в CORRECT_OPTION, что видно из кода
CASE CORRECT_OPTION. WHEN '+'. WORKINGDAY_INDICATOR = '+'. WHEN '-'. WORKINGDAY_INDICATOR = '-'. ENDCASE. Правда зачем так сложно, через CASE сделано, это нам наверное никто не подскажет, ну хотя может найдется тот индус, который это писал, а так может были какие мысли, да так и не реализовались. |
* Номер дня в неделе, понедельник считается первым днем, воскресение 7.
DATA: l_day LIKE scal-indicator. CALL FUNCTION 'DATE_COMPUTE_DAY' EXPORTING date = sy-datum IMPORTING day = l_day.
Для даты 16.05.2008 будет возвращен параметр 5.
* Функция возвращает дату представленную во внутреннем формате в нормальный формат, т.е. это обратная конвертация для функции DATE_CONVERT_TO_FACTORYDATE, которая описана выше. Обратите внимание, что поправка на рабочий день выполняется автоматически, т.е. к примеру, если вы укажите число 3995, что равно 01.01.2008, то будет возвращена дата 31.12.2007, т.е. фактически CORRECT_OPTION = '-'. Ну а остальное, вроде, как ясно из текста:
DATA: l_datum LIKE scal-date, l_factorydate LIKE scal-facdate. l_factorydate = '3 996'. CALL FUNCTION 'FACTORYDATE_CONVERT_TO_DATE' EXPORTING factorydate = l_factorydate factory_calendar_id = 'UA' IMPORTING date = l_date EXCEPTIONS calendar_buffer_not_loadable = 1 factorydate_after_range = 2 factorydate_before_range = 3 factorydate_invalid = 4 factory_calendar_id_missing = 5 factory_calendar_not_found = 6 OTHERS = 7.
Результат: 02.01.2008.
Функция позволяющая добавить или отнять месяцы от заданной даты, понимает високосный год.
DATA: l_date LIKE sy-datum. CALL FUNCTION 'MONTH_PLUS_DETERMINE' EXPORTING months = '1' olddate = '20080131' IMPORTING newdate = l_date.
Параметры:
- months - количество месяцев которое нужно добавить или отнять от даты. Для вычитания нужно записать значение как -1;
- olddate - дата от которой требуется вычесть месяцы;
- l_date - новое значение даты.
* Проверяет значение введенной даты на корректность и выдает, строку ошибки, которую можно показать пользователю, что не нравится в веденной им дате:
DATA: l_date LIKE vtb_market-ddate, l_sstats LIKE vtb_market-sstats, l_error_flg LIKE vtb_market-rupdhist, l_error_msg LIKE vtb_market-error. l_date = '301173'. CALL FUNCTION 'TB_DATAFEED_CHECK_DATE' EXPORTING date = l_date CHANGING sstats = l_sstats error_flg = l_error_flg error_msg = l_error_msg.
В ответ будет получено типа:
- l_sstats = E
- l_error_flg = X
- l_error_msg = Дата 301173 содержит недопустимый пробел!
* Проверка значения введенной даты. Так сказать еще одна вариация, когда проверяется, что введено.
function date_check_plausibility. *"---------------------------------------------------------------------- *"*"Lokale Schnittstelle: *" IMPORTING *" DATE LIKE SY-DATUM *" EXCEPTIONS *" PLAUSIBILITY_CHECK_FAILED *"---------------------------------------------------------------------- data: check_year_1 type p. data: check_year_2 type p. if date cn '0123456789'. message s011 with date raising plausibility_check_failed. endif. if date+4(2) lt '01' or date+4(2) gt '12'. message s003 with date+4(2) raising plausibility_check_failed. endif. if date+6(2) lt '01' or date+6(2) gt '31'. message s006 with date+6(2) raising plausibility_check_failed. endif. if date+4(2) eq '01' or date+4(2) eq '03' or date+4(2) eq '05' or date+4(2) eq '07' or date+4(2) eq '08' or date+4(2) eq '10' or date+4(2) eq '12'. if date+6(2) gt '31'. message s004 with date+6(2) date+4(2) raising plausibility_check_failed. endif. elseif date+4(2) eq '04' or date+4(2) eq '06' or date+4(2) eq '09' or date+4(2) eq '11'. if date+6(2) gt '30'. message s004 with date+6(2) date+4(2) raising plausibility_check_failed. endif. else. check_year_1 = date(4) mod 4. " alle 4 Jahre ist schaltjahr if check_year_1 eq 0. check_year_1 = date(4) mod 100. " aber nicht alle 100 Jahre check_year_2 = date(4) mod 400. " aber alle 400 Jahre if check_year_1 eq 0 and check_year_2 ne 0. if date+6(2) gt '28'. message s004 with date+6(2) date+4(2) raising plausibility_check_failed. endif. else. if date+6(2) gt '29'. message s004 with date+6(2) date+4(2) raising plausibility_check_failed. endif. endif. else. if date+6(2) gt '28'. message s004 with date+6(2) date+4(2) raising plausibility_check_failed. endif. endif. endif. endfunction.
* Возвращает начальную и конечную дату периода, для заданного варианта финансового года:
DATA: l_fday LIKE bkpf-budat, l_lday LIKE bkpf-budat, l_speriod LIKE bkpf-bstat. CALL FUNCTION 'PERIOD_DAY_DETERMINE' EXPORTING i_gjahr = '2009' i_monat = '02' i_periv = 'K4' IMPORTING e_fday = l_fday e_lday = l_lday e_speriod = l_speriod EXCEPTIONS error_period = 1 error_period_version = 2 firstday_not_defined = 3 period_not_defined = 4 year_invalid = 5 OTHERS = 6.
На выходе получим:
L_FDAY - 01.02.2009 Дата начала периода
L_LDAY - 28.02.2009 Дата конца периода
L_SPERIOD - SPACE - Признак специального периода проводки
L_FDAY - 01.02.2009 Дата начала периода
L_LDAY - 28.02.2009 Дата конца периода
L_SPERIOD - SPACE - Признак специального периода проводки
* Функция округления даты. В общем виде возвращает последний/первый день недели, месяца, года... иногда полезно, чтобы не вызвать кучу функций расчета даты:
DATA: l_datum LIKE sy-datum. l_datum = sy-datum. CALL FUNCTION 'ROUND_DATE' EXPORTING i_iprkz = '2' i_rdmhd = '+' CHANGING c_date = l_datum EXCEPTIONS invalid_round_rule = 1 OTHERS = 2. WRITE: / l_datum DD/MM/YYYY.
i_iprkz - код периода. Могут быть следующие значения:
- SPACE - день, смысла в этом коде нет, так как время не округляется, а возваращаемая дата = переданной дате;
- '1' = неделя, возвращает дату конца/начала недели;
- '2' = месяца, возвращает дату конца/начала месяца;
- '3' = год, возвращает дату конца/начала года.
i_rdmhd - направление округления:
- '+' - округление до конца периода, т.е. если задан код периода 2, то текущая дата будет округлена до конца периода и будет содержать дату последнего дня месяца.
- '-' - округление до начала периода, т.е. если задан код периода 2, то текущая дата будет округлена до начала периода и будет содержать дату первого дня месяца. Наверное, это не очень полезно, так как ясно, что дата = 01, а вот началом недели уже не так просто и придется считать.
- 'F' - округление до конца периода, при этом будет возвращаться следующий день за концом периода, т.е. если выбрано тип '1', то будет возращена дата понедельника следующей недели, тогда как при '+' возвращается дата воскресения.
* Позволяет получить от заданной даты новую дату в будущем, путем добавления месяцев и дней. Про високосный год знает:
DATA: l_result_date LIKE sy-datum. CALL FUNCTION 'CALCULATE_DATE' EXPORTING days = '1' months = '10' start_date = '20080228' IMPORTING result_date = l_result_date. WRITE: / l_result_date.
В данном примере возвращает 29.12.2008.
* Возвращает название дня недели по заданной дате, но только на английском языке, по этому примера нет, только наименование:
CALL FUNCTION 'DATE_TO_DAY' EXPORTING date = * IMPORTING * WEEKDAY =.
* Возвращает красивые строчки с расшифровками запрошенных дат, например, 11.02.2008 будут сформированы строки номер дня недели = 3, краткое название дня недели в виде "Ср", полное название дня "Среда" и название дня недели + дата в виде строки "Среда, 11.Март. 2009", в общем удобно, плюс знает, что это всё может быть написано на разных языках:
DATA: l_date_from LIKE sy-datum, l_date_to LIKE sy-datum, l_year_of_valid_from LIKE scal-year, l_year_of_valid_to LIKE scal-year, l_returncode LIKE sy-subrc, lt_day_attributes LIKE casdayattr OCCURS 1 WITH HEADER LINE. l_date_from = sy-datum. l_date_to = sy-datum + 7. CALL FUNCTION 'DAY_ATTRIBUTES_GET' EXPORTING * FACTORY_CALENDAR = ' ' * HOLIDAY_CALENDAR = ' ' date_from = l_date_from date_to = l_date_to language = sy-langu IMPORTING year_of_valid_from = l_year_of_valid_from year_of_valid_to = l_year_of_valid_to returncode = l_returncode TABLES day_attributes = lt_day_attributes EXCEPTIONS factory_calendar_not_found = 1 holiday_calendar_not_found = 2 date_has_invalid_format = 3 date_inconsistency = 4 OTHERS = 5. IF sy-subrc <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF.
Пример возвращенной таблички:
* Рассчитать количество месяцев между двумя датами. Если i_kz_incl_bis не равно SPACE, тогда к переданной дате i_datum_bis до начала вычислений добавляется один день, что само собой может увеличить/уменьшить количество месяцев на единицу:
DATA: l_datum_bis LIKE sy-datum, l_datum_von LIKE sy-datum, l_month TYPE i. l_datum_bis = sy-datum + 100. l_datum_von = sy-datum. CALL FUNCTION 'MONTHS_BETWEEN_TWO_DATES' EXPORTING i_datum_bis = l_datum_bis i_datum_von = l_datum_von i_kz_incl_bis = ' ' IMPORTING e_monate = l_month. WRITE: / l_month.
В данном примере l_month = 03.
* Проверяет является переданная дата последним днем месяца + если это високосный год, то второй параметр e_tt будет содержать признак високосной даты в году, параметр e_kz_ult = space дата не последняя дата месяца, "X" - дата является последним днем месяца:
DATA: l_kz_ult(1) TYPE c, l_tt TYPE i. CALL FUNCTION 'END_OF_MONTH_DETERMINE_2' EXPORTING i_datum = '20080329' IMPORTING e_kz_ult = l_kz_ult e_tt = l_tt.
* Расчёт времени в часах и минутах между двумя датами:
DATA: l_date1 LIKE sy-datum, l_time1 LIKE sy-uzeit, l_date2 LIKE sy-datum, l_time2 LIKE sy-uzeit, l_tdiff LIKE tvro-fahztd, l_date2_early LIKE rv56a-selkz. l_date1 = sy-datum. l_time1 = sy-uzeit + 5. l_date2 = sy-datum + 1. l_time2 = sy-uzeit + 76. CALL FUNCTION 'SD_CALC_DURATION_FROM_DATETIME' EXPORTING i_date1 = l_date1 i_time1 = l_time1 i_date2 = l_date2 i_time2 = l_time2 IMPORTING e_tdiff = l_tdiff e_date2_early = l_date2_early EXCEPTIONS invalid_datetime = 1 OTHERS = 2. IF sy-subrc <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. WRITE: / l_tdiff, / l_date2_early.
Параметр e_date2_early = Х, если i_date1 > i_date2, иначе равно SPACE.
* Рассчитывает время между двумя датами в минутах:
DATA: l_date1 LIKE sy-datum, l_time1 LIKE sy-uzeit, l_date2 LIKE sy-datum, l_time2 LIKE sy-uzeit, l_delta_time LIKE mcwmit-be_ae, l_delta_unit LIKE mcwmit-lzeit. l_date1 = sy-datum. l_time1 = sy-uzeit + 5. l_date2 = sy-datum + 1. l_time2 = sy-uzeit + 76. CALL FUNCTION 'L_MC_TIME_DIFFERENCE' EXPORTING date_from = l_date1 date_to = l_date2 time_from = l_time1 time_to = l_time2 IMPORTING delta_time = l_delta_time delta_unit = l_delta_unit EXCEPTIONS from_greater_to = 1 OTHERS = 2. IF sy-subrc <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. WRITE: / l_delta_time, / l_delta_unit.
* Возвращает не только текущий год, но и месяц. Фактически - текущий открытый период:
DATA: l_currm LIKE bkpf-monat, l_curry LIKE bkpf-gjahr, l_prevm LIKE bkpf-monat, l_prevy LIKE bkpf-gjahr. CALL FUNCTION 'GET_CURRENT_YEAR' EXPORTING bukrs = '1000' date = sy-datum IMPORTING currm = l_currm curry = l_curry prevm = l_prevm prevy = l_prevy.
* Возвращает различное представление даты в формате пользователя. Рекомендуется использовать для формирования строк даты при передаче в батч-интпуты, так как там данные должны быть введены с разделителями пользователя:
DATA: l_mdat4(5) TYPE c, l_mdat6(7) TYPE c, l_tdat4(5) TYPE c, l_tdat6(8) TYPE c, l_tdat8(10) TYPE c, l_wdat4(5) TYPE c, l_wdat6(7) TYPE c. CALL FUNCTION 'DATUMSAUFBEREITUNG' EXPORTING flagm = 'X' flagw = 'X' idate = sy-datum * IMONT = ' ' * IWEEK = ' ' IMPORTING mdat4 = l_mdat4 mdat6 = l_mdat6 tdat4 = l_tdat4 tdat6 = l_tdat6 tdat8 = l_tdat8 wdat4 = l_wdat4 wdat6 = l_wdat6 EXCEPTIONS datfm_ungueltig = 1 datum_ungueltig = 2 OTHERS = 3. WRITE: / l_mdat4, / l_mdat6, / l_tdat4, / l_tdat6, / l_tdat8, / l_wdat4, / l_wdat6.
Пример:
* Позволяет к заданной дате добавить требуемое количество месяцев. Помнит про високосный год:
DATA: l_stdate LIKE sy-datum, l_count TYPE i, l_eddate LIKE sy-datum. l_stdate = sy-datum. l_count = '5'. CALL FUNCTION 'RE_ADD_MONTH_TO_DATE' EXPORTING months = l_count olddate = l_stdate IMPORTING newdate = l_eddate. WRITE: / 'Начальная дата:', l_stdate, / '+', l_count, 'месяцев', / 'Конечная дата:', l_eddate.
* Позволяет получить следующее время и дату путем добавления часов, минут и секунд. На вход передаем дату и время, например текущие и время в формате HHMMSS, которое нужно добавить. На выходе получаем новую дату и время:
DATA: l_uzeit LIKE sy-datum, l_uzeit LIKE sy-uzeit. CALL FUNCTION 'DIMP_ADD_TIME' EXPORTING iv_starttime = sy-uzeit iv_startdate = sy-datum iv_addtime = '000001' IMPORTING ev_endtime = l_uzeit ev_enddate = l_erdat.
* Данная функция позволяет получить код/номер периода для заданной даты. В общем виде для варианта финансового года К4, данная задача не является проблемной, номер месяца и есть номер периода, но стандартно в системе могут быть созданы различные варианты финансовых периодов, в банках любят обычно использовать вариант типа 365 периодов в году. Самый простой случай - это работа с кварталом:
DATA: l_period LIKE t009-anzbp, l_year LIKE t009b-bdatj. CALL FUNCTION 'DETERMINE_PERIOD' EXPORTING date = sy-datum * PERIOD_IN = '00' version = 'Q1' "Вариант финансового года (кварталы) IMPORTING period = l_period year = l_year EXCEPTIONS period_in_not_valid = 1 period_not_assigned = 2 version_undefined = 3 OTHERS = 4.
Переменная PERIOD_IN используется для определения существования особых периодов для варианта финансового года. Правда работает она только в случае если дата задана для последнего возможного периода в варианте года, тогда например для вариант К4, обычно 12 периодов + 4 особых периода, при вызове для любой из дат в диапазоне 01.12 по 31.12 и задании например PERIOD_IN = 18 система будет выдавать ошибку, особый период не существует, если же вызвать с PERIOD_IN = 13, ошибки не будет.
* Возвращает дату начала и конца квартала, в который входит переданная дата:
DATA: l_start LIKE sy-tabix, l_end LIKE sy-tabix. CALL FUNCTION 'ISH_QUARTER_GET' EXPORTING ss_date = sy-datum IMPORTING ss_begin = l_start ss_end = l_end EXCEPTIONS error = 1 wrong_date = 2 OTHERS = 3.
Например для даты 15.09.2012 вернет значения:
Begin: 01.07.2012, End: 30.09.2012.
Begin: 01.07.2012, End: 30.09.2012.
* Возвращает для заданной даты, номер дня в неделе и название дня недели. Название дня в неделе выполняется путем вывода текстовой константы на английском и большими буквами:
DATA: l_day LIKE scal-indicator, l_weekday TYPE sc_day_txt. CALL FUNCTION 'DATE_COMPUTE_DAY_ENHANCED' EXPORTING date = sy-datum IMPORTING day = l_day weekday = l_weekday. WRITE: / 'Номер дня в неделе:', l_day, 'День недели:', l_weekday.
Data: l_year_of_valid_from LIKE scal-year, l_year_of_valid_to LIKE scal-year, l_returncode LIKE sy-subrc, l_date_from LIKE scal-date, l_date_to LIKE scal-date, lt_day_attributes LIKE casdayattr OCCURS 1 WITH HEADER LINE. l_date_from = '20130101'. l_date_to = '20130104'. CALL FUNCTION 'DAY_ATTRIBUTES_GET' EXPORTING * FACTORY_CALENDAR = ' ' * HOLIDAY_CALENDAR = ' ' date_from = l_date_from date_to = l_date_to language = sy-langu non_iso = ' ' IMPORTING year_of_valid_from = l_year_of_valid_from year_of_valid_to = l_year_of_valid_to returncode = l_returncode TABLES day_attributes = lt_day_attributes EXCEPTIONS factory_calendar_not_found = 1 holiday_calendar_not_found = 2 date_has_invalid_format = 3 date_inconsistency = 4 OTHERS = 5. IF sy-subrc <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF.
Пример таблицы результата:
* Возвращает кол-во лет, месяцев, дней между 2-мя датами.
Для точности отнять от даты окончания один день
t_date = t_date - 1.
CALL FUNCTION 'HR_HK_DIFF_BT_2_DATES'
EXPORTING
date1 = t_date
date2 = t_dat01
output_format = '05'
IMPORTING
years = years
months = months
days = days
EXCEPTIONS
invalid_dates_specified = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
*****
ОтветитьУдалитьISH_QUARTER_GET - Его больше нет в sap
ОтветитьУдалить