Вычислить сколько месяцев в указанном периоде?
Подскажите, пожалуйста. Мне необходимо в запросе вичислить сколько у меня содержиться месяцев в периоде например с 01.11.2011 по 25.07.2012. Если я делаю так - РАЗНОСТЬДАТ(&Дата1, &Дата2, МЕСЯЦ), то получаю только целое число месяцев 8, а часть текущего месяца, т.е 25 дней мне надо получить как 0,8 месяца. Как это можно сделать?
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Задача стоит в том, чтобы вычислить среднемесячную оплату, для расчета которой необходимо сумма оплаты за период деленная на колиество месяцев. От точность количества месяцев будет зависит точность среднемесячной оплаты.
У вас люди без выходных и в новый год тоже работают? Тогда считайте ровно 365/12 ~ 30,4 - ваше право. Более того, на эту величину вам только "хвостик" делить надо, а не всю разность дат. Для наименьшей погрешности.
Вот искал решение похожей задачки, наткнулся на этот пост.
Не придумал ничего более подходящего кроме как писать самому.
Делюсь с сообществом процедуркой. Процедура рекурсивна маленько, можете пинать за это, зато самодостаточна))
Не придумал ничего более подходящего кроме как писать самому.
Делюсь с сообществом процедуркой. Процедура рекурсивна маленько, можете пинать за это, зато самодостаточна))
//НачалоПериода - Дата
//КонецПериода - Дата
//Интервал - Строка - "День", "Месяц", "Год"
//СДробями - Булево - возвращать дробную часть разности или нет
//Точность - Число - Количество дробных знаков
Функция ДробнаяРазностьДат(НачалоПериода, КонецПериода, Интервал ,СДробями = Ложь,Точность = 0)
Разность = 0;
Если СДробями = Ложь Тогда
Если НачалоПериода > КонецПериода Тогда
Дата1 = КонецПериода;
Дата2 = НачалоПериода;
Иначе
Дата1 = НачалоПериода;
Дата2 = КонецПериода;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗНОСТЬДАТ(&Дата1, &Дата2,"+СокрЛП(Интервал)+") КАК Разность";
Запрос.УстановитьПараметр("Дата1",Дата1);
Запрос.УстановитьПараметр("Дата2",Дата2);
Результат = Запрос.Выполнить().Выбрать();
Результат.Следующий();
Если СокрЛП(Интервал) = "ДЕНЬ" Тогда
Разность = Результат.Разность + 1;
Иначе
Разность = Результат.Разность;
КонецЕсли;
Иначе
//ДЕНЬ
Если СокрЛП(Интервал) = "День" Тогда
//Здесь всё просто, делим разность в секундах на количество секунд в дне (86400) и округляем до нужной точности
Разность = Окр(((КонецПериода - НачалоПериода))/86400,Точность);
ИначеЕсли СокрЛП(Интервал) = "Месяц" Тогда //МЕСЯЦ
//Проверим простой вариант - обе даты в одном месяце
Если НачалоМесяца(НачалоПериода) = НачалоМесяца(КонецПериода) Тогда
СекундВМесяце = КонецМесяца(НачалоПериода) - НачалоМесяца(НачалоПериода) + 1;
СекундВИнтервале = КонецДня(КонецПериода) - НачалоДня(НачалоПериода) + 1;
Разность = Окр((СекундВИнтервале / СекундВМесяце),Точность)
Иначе
//Проверим, начинается ли интервал целым месяцем и заканчивается ли целым
ЕстьДробныйМесяцНач = Ложь; //Признак того будут ли дробные части месяца
ЕстьДробныйМесяцКон = Ложь; //Признак того будут ли дробные части месяца
Если НачалоМесяца(НачалоПериода) = НачалоДня(НачалоПериода) тогда
Дата1 = НачалоДня(НачалоПериода);
Иначе
Дата1 = КонецМесяца(НачалоПериода)+1; //Сдвинемся на начало следующего месяца
ЕстьДробныйМесяцНач = Истина;
КонецЕсли;
Если КонецМесяца(КонецПериода) = КонецДня(КонецПериода) Тогда
Дата2 = КонецДня(КонецПериода);
Иначе
Дата2 = НачалоМесяца(КонецПериода)-1; //Сдвинемся на конец предыдущего месяца
ЕстьДробныйМесяцКон = Истина;
КонецЕсли;
ЦелыхМесяцев = 0;
ДробныхМесяцев = 0;
//Получим число целых месяцев;
Разность = ДробнаяРазностьДат(Дата1, Дата2,"Месяц",Ложь) + 1;
//Теперь будем считать дробные части месяца
Если ЕстьДробныйМесяцНач Тогда
СекундВМесяце = КонецМесяца(НачалоПериода) - НачалоМесяца(НачалоПериода) + 1;
СекундВИнтервале = КонецМесяца(НачалоПериода) - НачалоДня(НачалоПериода) + 1; //
Разность = Разность + Окр((СекундВИнтервале / СекундВМесяце),Точность);
КонецЕсли;
Если ЕстьДробныйМесяцКон Тогда
СекундВМесяце = КонецМесяца(КонецПериода) - НачалоМесяца(КонецПериода) + 1;
СекундВИнтервале = КонецДня(КонецПериода) - НачалоМесяца(НачалоПериода) + 1; //
Разность = Разность + Окр((СекундВИнтервале / СекундВМесяце),Точность);
КонецЕсли;
КонецЕсли;
ИначеЕсли СокрЛП(Интервал) = "Год" Тогда //ГОД
//Проверим сначала простой вариант, если обе даты в одном году
Если НачалоГода(НачалоПериода) = НачалоГода(КонецПериода) Тогда
СекундВГоду = КонецГода(КонецПериода) - НачалоГода(НачалоПериода);
СекундВИнтервале = КонецПериода - НачалоПериода;
Разность = Окр((СекундВИнтервале / СекундВГоду),Точность);
Иначе //Даты в разных годах, тут будем считать
ЕстьДробныйГодНач = Ложь;
ЕстьДробныйГодКон = Ложь;
Если НачалоГода(НачалоПериода) = НачалоДня(НачалоПериода) Тогда
Дата1 = НачалоДня(НачалоПериода);
Иначе
Дата1 = КонецГода(НачалоПериода) + 1; //Переносим дату на начало следующего года
ЕстьДробныйГодНач = Истина;
КонецЕсли;
Если КонецГода(КонецПериода) = КонецДня(КонецПериода) Тогда
Дата2 = КонецДня(КонецПериода);
Иначе
Дата2 = НачалоГода(КонецПериода) - 1; // Переносим на конец предыдущего года;
КонецЕсли;
ЦелыхЛет = ДробнаяРазностьДат(Дата1, Дата2, "Год", Ложь);
Разность = ЦелыхЛет;
Если ЕстьДробныйГодНач Тогда
СекундВГоду = КонецГода(НачалоПериода) - НачалоГода(НачалоПериода);
ДробныхЛет = КонецГода(НачалоПериода) - НачалоПериода;
Разность = Разность + Окр((ДробныхЛет / СекундВГоду),Точность)
КонецЕсли;
Если ЕстьДробныйГодКон Тогда
СекундВГоду = КонецГода(КонецПериода) - НачалоГода(КонецПериода);
ДробныхЛет = КонецПериода - НачалоГода(КонецПериода);
Разность = Разность + Окр((ДробныхЛет / СекундВГоду),Точность)
КонецЕсли;
КонецЕсли;
Иначе
Разность = НачалоПериода - КонецПериода;
КонецЕсли;
КонецЕсли; //интервалы
Возврат Разность
КонецФункции
Показать
(20)
Тоже искал решение похожей задачки, наткнулся на ваш пост.
Добавил возможность округления всегда вверх до заданной точности и исправил подсчет месяцев и лет, было напутано в подсчете секунд в дробных периодах!
Тоже искал решение похожей задачки, наткнулся на ваш пост.
Добавил возможность округления всегда вверх до заданной точности и исправил подсчет месяцев и лет, было напутано в подсчете секунд в дробных периодах!
//Интервал - Строка - "День", "Месяц", "Год"
//СДробями - Булево - возвращать дробную часть разности или нет
//Точность - Число - Количество дробных знаков
//ОкрВверх - Булево - Округляет до заданной точности или нет
&НаСервере
Функция ДробнаяРазностьДат(НачалоПериода, КонецПериода, Интервал, СДробями = Ложь, Точность = 0, ОкрВверх = Ложь)
Если СДробями = Ложь Тогда
Дата1 = ?(НачалоПериода > КонецПериода, КонецПериода, НачалоПериода);
Дата2 = ?(НачалоПериода > КонецПериода, НачалоПериода, КонецПериода);
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗНОСТЬДАТ(&Дата1, &Дата2,"+СокрЛП(Интервал)+") КАК Разность";
Запрос.УстановитьПараметр("Дата1",Дата1);
Запрос.УстановитьПараметр("Дата2",Дата2);
Результат = Запрос.Выполнить().Выбрать();
Результат.Следующий();
Разность = ?(СокрЛП(Интервал) = "ДЕНЬ", Результат.Разность + 1, Результат.Разность);
Иначе
//ДЕНЬ
Если СокрЛП(Интервал) = "День" Тогда
//Здесь всё просто, делим разность в секундах на количество секунд в дне (86400) и округляем до нужной точности
Разность = Окр(((КонецПериода - НачалоПериода))/86400 + ?(ОкрВверх, 5 * Pow(10, -Точность - 1), 0), Точность);
//МЕСЯЦ
ИначеЕсли СокрЛП(Интервал) = "Месяц" Тогда
//Проверим простой вариант - обе даты в одном месяце
Если НачалоМесяца(НачалоПериода) = НачалоМесяца(КонецПериода) Тогда
СекундВМесяце = КонецМесяца(НачалоПериода) - НачалоМесяца(НачалоПериода) + 1;
СекундВИнтервале = КонецДня(КонецПериода) - НачалоДня(НачалоПериода) + 1;
Разность = Окр((СекундВИнтервале / СекундВМесяце) + ?(ОкрВверх, 5 * Pow(10, -Точность - 1), 0), Точность);
Иначе
//Проверим, начинается ли интервал целым месяцем и заканчивается ли целым
ЕстьДробныйМесяцНач = Не НачалоМесяца(НачалоПериода) = НачалоДня(НачалоПериода); //Признак того будут ли дробные части месяца
ЕстьДробныйМесяцКон = Не КонецМесяца(КонецПериода) = КонецДня(КонецПериода); //Признак того будут ли дробные части месяца
Дата1 = ?(ЕстьДробныйМесяцНач, КонецМесяца(НачалоПериода)+1, НачалоДня(НачалоПериода));
Дата2 = ?(ЕстьДробныйМесяцКон, НачалоМесяца(КонецПериода)-1, КонецДня(КонецПериода));
Разность = ДробнаяРазностьДат(Дата1, Дата2,"Месяц",Ложь) + 1;
//Теперь будем считать дробные части месяца
СекундВМесяце = ?(ЕстьДробныйМесяцНач, КонецМесяца(НачалоПериода) - НачалоМесяца(НачалоПериода) + 1, 0) + ?(ЕстьДробныйМесяцКон, КонецМесяца(КонецПериода) - НачалоМесяца(КонецПериода) + 1, 0);
СекундВИнтервале = ?(ЕстьДробныйМесяцНач, КонецМесяца(НачалоПериода) - НачалоДня(НачалоПериода) + 1, 0) + ?(ЕстьДробныйМесяцКон, КонецДня(КонецПериода) - НачалоМесяца(КонецПериода) + 1, 0); //
Разность = ?(Не ЕстьДробныйМесяцНач И Не ЕстьДробныйМесяцКон, Разность, Разность + Окр((СекундВИнтервале / СекундВМесяце) + ?(ОкрВверх, 5 * Pow(10, -Точность - 1), 0), Точность));
КонецЕсли;
//ГОД
ИначеЕсли СокрЛП(Интервал) = "Год" Тогда
//Проверим сначала простой вариант, если обе даты в одном году
Если НачалоГода(НачалоПериода) = НачалоГода(КонецПериода) Тогда
СекундВГоду = КонецГода(КонецПериода) - НачалоГода(НачалоПериода);
СекундВИнтервале = КонецПериода - НачалоПериода;
Разность = Окр((СекундВИнтервале / СекундВГоду),Точность);
Иначе //Даты в разных годах, тут будем считать
ЕстьДробныйГодНач = Не НачалоГода(НачалоПериода) = НачалоДня(НачалоПериода);
ЕстьДробныйГодКон = Не КонецГода(КонецПериода) = КонецДня(КонецПериода);
Дата1 = ?(ЕстьДробныйГодНач, КонецГода(НачалоПериода) + 1, НачалоДня(НачалоПериода));
Дата2 = ?(ЕстьДробныйГодКон, НачалоГода(КонецПериода), КонецДня(КонецПериода));
Разность = ДробнаяРазностьДат(Дата1, Дата2, "Год", Ложь);
//Теперь будем считать дробные части года
СекундВГоду = ?(ЕстьДробныйГодНач, КонецГода(НачалоПериода) - НачалоГода(НачалоПериода), 0) + ?(ЕстьДробныйГодКон, КонецГода(КонецПериода) - НачалоГода(КонецПериода), 0);
ДробныхЛет = ?(ЕстьДробныйГодНач, КонецГода(НачалоПериода) - НачалоПериода, 0) + ?(ЕстьДробныйГодКон, КонецПериода - НачалоГода(КонецПериода), 0);
Разность = ?(Не ЕстьДробныйГодНач И Не ЕстьДробныйГодКон, Разность, Разность + Окр((ДробныхЛет / СекундВГоду) + ?(ОкрВверх, 5 * Pow(10, -Точность - 1), 0), Точность));
КонецЕсли;
Иначе
Разность = НачалоПериода - КонецПериода;
КонецЕсли;
КонецЕсли; //интервалы
Возврат Разность;
КонецФункции
Показать
(29)
Только после того как здесь вставил свой код увидел свой косяк с округлением всегда вверх
Вместо:
Разность = Окр((СекундВИнтервале / СекундВГоду),Точность);
Иначе //Даты в разных годах, тут будем считать
Надо:
Разность = Окр((СекундВИнтервале / СекундВГоду) + ?(ОкрВверх, 5 * Pow(10, -Точность - 1), 0), Точность);
Только после того как здесь вставил свой код увидел свой косяк с округлением всегда вверх
Вместо:
Разность = Окр((СекундВИнтервале / СекундВГоду),Точность);
Иначе //Даты в разных годах, тут будем считать
Надо:
Разность = Окр((СекундВИнтервале / СекундВГоду) + ?(ОкрВверх, 5 * Pow(10, -Точность - 1), 0), Точность);
"кусок месяца" от второй даты
РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), Дата2, ДЕНЬ)
"кусок месяца" от первой даты даты
РАЗНОСТЬДАТ(Дата1, КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), ДЕНЬ)
число дней в месяце:
РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ), КОНЕЦПЕРИОДА(Дата, МЕСЯЦ), ДЕНЬ)
Итоговая формула
Кусок1 / ЧислоДней1 + ЦелыхМесяцевМежду + Кусок2 / ЧислоДней2
Целых месяцев между двумя датами:
РАЗНОСТЬДАТ(КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), МЕСЯЦ)
Итоговая формула в запрос:
РАЗНОСТЬДАТ(Дата1, КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), ДЕНЬ) / РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата1, МЕСЯЦ), КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), ДЕНЬ) + РАЗНОСТЬДАТ(КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), МЕСЯЦ) + РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), Дата2, ДЕНЬ) / РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), КОНЕЦПЕРИОДА(Дата2, МЕСЯЦ), ДЕНЬ)
РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), Дата2, ДЕНЬ)
"кусок месяца" от первой даты даты
РАЗНОСТЬДАТ(Дата1, КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), ДЕНЬ)
число дней в месяце:
РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ), КОНЕЦПЕРИОДА(Дата, МЕСЯЦ), ДЕНЬ)
Итоговая формула
Кусок1 / ЧислоДней1 + ЦелыхМесяцевМежду + Кусок2 / ЧислоДней2
Целых месяцев между двумя датами:
РАЗНОСТЬДАТ(КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), МЕСЯЦ)
Итоговая формула в запрос:
РАЗНОСТЬДАТ(Дата1, КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), ДЕНЬ) / РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата1, МЕСЯЦ), КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), ДЕНЬ) + РАЗНОСТЬДАТ(КОНЕЦПЕРИОДА(Дата1, МЕСЯЦ), НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), МЕСЯЦ) + РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), Дата2, ДЕНЬ) / РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Дата2, МЕСЯЦ), КОНЕЦПЕРИОДА(Дата2, МЕСЯЦ), ДЕНЬ)
(21) естественно, это все без привязки к календарю, просто расчет месяцев
Ради интереса залез в отладчик, посмотреть, как это работает. Неверно считаются месяцы между концом месяца начальной даты и началом месяца конечной (средняя часть). В тестовом примере (взял 15.01.2013 и 28.03.2013) было 29 дней и 2 месяца (февраль с 28 днями посчитался за 2), хотя должно быть 28 дней и 1 месяц. Видимо дело сделала 1 секунда, которая остается при вызове КОНЕЦПЕРИОДА. Решилось использованием конструкции ДОБАВИТЬКДАТЕ:
РАЗНОСТЬДАТ(&Дата1, КОНЕЦПЕРИОДА(&Дата1, МЕСЯЦ), ДЕНЬ) / РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&Дата1, МЕСЯЦ), КОНЕЦПЕРИОДА(&Дата1, МЕСЯЦ), ДЕНЬ) + РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(КОНЕЦПЕРИОДА(&Дата1, МЕСЯЦ), СЕКУНДА, 1), НАЧАЛОПЕРИОДА(&Дата2, МЕСЯЦ), МЕСЯЦ) + РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&Дата2, МЕСЯЦ), &Дата2, ДЕНЬ) / РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&Дата2, МЕСЯЦ), КОНЕЦПЕРИОДА(&Дата2, МЕСЯЦ), ДЕНЬ)
для тестового примера получается 16 / 30 + 1 + 27 / 30 = 2.43
Здесь остается вопрос в числах: 16 (при дате 15) и 28 (при дате 27)
Очевидно, здесь просто надо решить, считать ли заданный день как прошедший, если нет. Если считать - то все верно. Если не считать, то надо добавлять к параметрам &Дата1 и &Дата2 КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)
Ради интереса залез в отладчик, посмотреть, как это работает. Неверно считаются месяцы между концом месяца начальной даты и началом месяца конечной (средняя часть). В тестовом примере (взял 15.01.2013 и 28.03.2013) было 29 дней и 2 месяца (февраль с 28 днями посчитался за 2), хотя должно быть 28 дней и 1 месяц. Видимо дело сделала 1 секунда, которая остается при вызове КОНЕЦПЕРИОДА. Решилось использованием конструкции ДОБАВИТЬКДАТЕ:
РАЗНОСТЬДАТ(&Дата1, КОНЕЦПЕРИОДА(&Дата1, МЕСЯЦ), ДЕНЬ) / РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&Дата1, МЕСЯЦ), КОНЕЦПЕРИОДА(&Дата1, МЕСЯЦ), ДЕНЬ) + РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(КОНЕЦПЕРИОДА(&Дата1, МЕСЯЦ), СЕКУНДА, 1), НАЧАЛОПЕРИОДА(&Дата2, МЕСЯЦ), МЕСЯЦ) + РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&Дата2, МЕСЯЦ), &Дата2, ДЕНЬ) / РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&Дата2, МЕСЯЦ), КОНЕЦПЕРИОДА(&Дата2, МЕСЯЦ), ДЕНЬ)
для тестового примера получается 16 / 30 + 1 + 27 / 30 = 2.43
Здесь остается вопрос в числах: 16 (при дате 15) и 28 (при дате 27)
Очевидно, здесь просто надо решить, считать ли заданный день как прошедший, если нет. Если считать - то все верно. Если не считать, то надо добавлять к параметрам &Дата1 и &Дата2 КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)
Мне помогло вот:
Функция ВычислениеКоличестваМесяцев(ДатаНач, ДатаКон)
КоличествоМесяцев=0;
//сперва все переводим в систему СИ и года приводим к месяцам, добавляем нужное нам количество месяцев и
//вычитаем из подобноприведенного выражения количество месяцев в начале периода
КоличествоМесяцев = (Год(ДатаКон)*12+Месяц(ДатаКон)) - (Год(ДатаНач)*12+Месяц(ДатаНач));
Возврат КоличествоМесяцев;
КонецФункции
Показать
(23) Alever, А сколько месяцев выдаст ваша функция между 2014.01.31 и 2014.02.01?
Модифицировал функцию, показанную в документации в качестве примера вычисления стажа:
Если надо не целую часть месяца, то убрать округление.
Модифицировал функцию, показанную в документации в качестве примера вычисления стажа:
Функция РазницаВМесяцах(ДатаНач, ДатаКон)
Лет1 = Год(ДатаНач);
Месяцев1 = Месяц(ДатаНач);
Если НачалоДня(ДатаНач) <> НачалоДня(КонецМесяца(ДатаНач)) Тогда
Дней1 = День(ДатаНач);
Иначе
Дней1 = 30;//В каждом месяце ровно 30 дней
КонецЕсли;
Лет2 = Год(ДатаКон);
Месяцев2 = Месяц(ДатаКон);
Если НачалоДня(ДатаКон) <> НачалоДня(КонецМесяца(ДатаКон)) Тогда
Дней2 = День(ДатаКон);
Иначе
Дней2 = 30;//В каждом месяце ровно 30 дней
КонецЕсли;
Лет = Лет2 - Лет1;
Месяцев = Месяцев2 - Месяцев1;
Дней = Дней2 - Дней1;
Возврат Цел(Лет*12 + Месяцев + Дней/30);
КонецФункции
ПоказатьЕсли надо не целую часть месяца, то убрать округление.
Хочу поделиться и своей функцией подсчета количества месяцев
//Считаем количество месяцев между датами
&НаКлиенте
Функция КоличествоМесяцевМеждуДатами(НачальнаяДата, КонечнаяДата)
МесяцНачальнойДаты = Месяц(НачальнаяДата);
МесяцКонечнойДаты = Месяц(КонечнаяДата);
КоличествоЛет = Год(ТекущаяДата()) - Год(НачальнаяДата);
Возврат КоличествоЛет * 12 - МесяцНачальнойДаты + МесяцКонечнойДаты;
КонецФункции
//Считаем количество месяцев между датами
&НаКлиенте
Функция КоличествоМесяцевМеждуДатами(НачальнаяДата, КонечнаяДата)
МесяцНачальнойДаты = Месяц(НачальнаяДата);
МесяцКонечнойДаты = Месяц(КонечнаяДата);
КоличествоЛет = Год(ТекущаяДата()) - Год(НачальнаяДата);
Возврат КоличествоЛет * 12 - МесяцНачальнойДаты + МесяцКонечнойДаты;
КонецФункции
(25) cheiser1982, у вас в формуле текущая дата - так задумано?
Может хотя бы как-то так должно быть?
Хотя все-таки функция представленная выше с принятием среднего числа дней в месяце будет точнее.
Может хотя бы как-то так должно быть?
Функция КоличествоМесяцевМеждуДатами1(НачальнаяДата, КонечнаяДата)
Возврат (Год(КонечнаяДата) - Год(НачальнаяДата)) * 12 - Месяц(НачальнаяДата) + Месяц(КонечнаяДата) + ?(День(КонечнаяДата) < День(НачальнаяДата), -1, 0);
КонецФункции
Хотя все-таки функция представленная выше с принятием среднего числа дней в месяце будет точнее.
Делюсь со всеми определением количества месяцев в указанном периоде запросом:
Запрос = Новый Запрос();
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
Запрос.Текст = "ВЫБРАТЬ
| 1 КАК Единица
|ПОМЕСТИТЬ Единицы
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 2
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 3
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 4
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 5
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 6
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 7
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 8
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 9
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| 10
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, 1000 * (Тысячи.Единица - 1) + 100 * (Сотни.Единица - 1) + 10 * (Десятки.Единица - 1) + Единицы.Единица - 1), МЕСЯЦ)) КАК КоличествоМесяцевВПериоде
|ИЗ
| Единицы КАК Единицы,
| Единицы КАК Десятки,
| Единицы КАК Сотни,
| Единицы КАК Тысячи
|ГДЕ
| ДОБАВИТЬКДАТЕ(&НачалоПериода, ДЕНЬ, 1000 * (Тысячи.Единица - 1) + 100 * (Сотни.Единица - 1) + 10 * (Десятки.Единица - 1) + Единицы.Единица - 1) <= &КонецПериода";
Выборка1 = РезультатЗапроса.Выбрать();
КоличествоМесяцевВПериоде = 0;
Пока Выборка1.Следующий() Цикл
КоличествоМесяцевВПериоде = Выборка1.КоличествоМесяцевВПериоде;
КонецЦикла;
Показать
С учетом вхождения в период расчета начальной и конечной даты
Пример: НачальнаяДата = '2022.01.01'; КонечнаяДата = '2022.01.31'; Имеем полый месяц.
ДобМес = ?(НачалоДня(НачальнаяДата) = НачалоМесяца(НачальнаяДата) И КонецДня(КонечнаяДата) = КонецМесяца(КонечнаяДата), 1, 0);
РазницаМесяц = (Год(КонечнаяДата) - Год(НачальнаяДата)) * 12 - Месяц(НачальнаяДата) + Месяц(КонечнаяДата) + ?(День(КонечнаяДата) < День(НачальнаяДата), -1, 0) + ДобМес;
Пример: НачальнаяДата = '2022.01.01'; КонечнаяДата = '2022.01.31'; Имеем полый месяц.
ДобМес = ?(НачалоДня(НачальнаяДата) = НачалоМесяца(НачальнаяДата) И КонецДня(КонечнаяДата) = КонецМесяца(КонечнаяДата), 1, 0);
РазницаМесяц = (Год(КонечнаяДата) - Год(НачальнаяДата)) * 12 - Месяц(НачальнаяДата) + Месяц(КонечнаяДата) + ?(День(КонечнаяДата) < День(НачальнаяДата), -1, 0) + ДобМес;
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот