Функция возвращающая разность дат в днях и месяцах.УТ 11.4
Добрый день,уважаемые форумчане!
Нужна функция,которая бы возвращала разницу в днях и месяцах между датами.
Нашел вот такой пример:
Но от части он мне не совсем подходит,т.к. например если мне вернется число 28 - 31 то это уже месяц:)
Может кто сталкивался с такой задачей?
Нужна функция,которая бы возвращала разницу в днях и месяцах между датами.
Нашел вот такой пример:
РазницаВДнях = (НачалоДня(ДатаОкончания) - НачалоДня(ДатаНачала)) / (60 * 60 * 24);
Но от части он мне не совсем подходит,т.к. например если мне вернется число 28 - 31 то это уже месяц:)
Может кто сталкивался с такой задачей?
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1)
И до некоторых очень туго доходит, что НЕТ универсального единого способа расчета разницы в единицах нефиксированного размера.
Вам в каких месяцах нужна разница? Январях? Апрелях? Или может февралях? А как насчет високосных февралей?
Из-за этого существуют свои собственные алгоритмы расчета таких сроков для конкретных назначений. Например, для стажей работы их несколько штук в зависимости от того какой конкретно стаж надо посчитать.
Потому не пытайтесь найти черную кошку в черной комнате, ее там нет, и пишите алгоритм, который требуется вашим клиентам и не занимайтесь при этом отсебятиной. Если, конечно, не подходит один из уже существующих.
Может кто сталкивался с такой задачей?
Все сталкивались с такой задачей.
И до некоторых очень туго доходит, что НЕТ универсального единого способа расчета разницы в единицах нефиксированного размера.
Вам в каких месяцах нужна разница? Январях? Апрелях? Или может февралях? А как насчет високосных февралей?
Из-за этого существуют свои собственные алгоритмы расчета таких сроков для конкретных назначений. Например, для стажей работы их несколько штук в зависимости от того какой конкретно стаж надо посчитать.
Потому не пытайтесь найти черную кошку в черной комнате, ее там нет, и пишите алгоритм, который требуется вашим клиентам и не занимайтесь при этом отсебятиной. Если, конечно, не подходит один из уже существующих.
(1)И посыпались очередные попытки что-то написать совершенно не зная какой именно алгоритм расчета нужен топикстартеру. И каждый лепит алгоритм по своим, никому другому не известным умолчаниям, которые, однако, могут ну никак не совпадать с умолчаниями, подразумеваемыми тем же топикстатртером. Он и сам то может не о всех условиях расчета знает, но народ строчит...
Еще раз - какой месяц используем? Усредненный? Фиксированный 30 дней? Как обсчитывать граничные месяцы? И т.д.
Еще раз - какой месяц используем? Усредненный? Фиксированный 30 дней? Как обсчитывать граничные месяцы? И т.д.
РазностьДат (DateDiff)
Функция предназначена для получения разницы между двумя датами.
Синтаксис:
РазностьДат(Выражение1 , Выражение2 , ТипРазности)
Параметры:
Выражение1 - тип Дата. Вычитаемая дата;
Выражение2 - тип Дата. Исходная дата;
ТипРазности - тип Строка. Содержит одно из значений:
Секунда;
Минута;
Час;
День;
Месяц;
Квартал;
Год.
Пример:
РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2002, 10, 12, 10, 15, 34),
ДАТАВРЕМЯ(2002, 10, 14, 9, 18, 06), "ДЕНЬ")
Результат:
2
Функция предназначена для получения разницы между двумя датами.
Синтаксис:
РазностьДат(Выражение1 , Выражение2 , ТипРазности)
Параметры:
Выражение1 - тип Дата. Вычитаемая дата;
Выражение2 - тип Дата. Исходная дата;
ТипРазности - тип Строка. Содержит одно из значений:
Секунда;
Минута;
Час;
День;
Месяц;
Квартал;
Год.
Пример:
РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2002, 10, 12, 10, 15, 34),
ДАТАВРЕМЯ(2002, 10, 14, 9, 18, 06), "ДЕНЬ")
Результат:
2
Из ЗУП 3.1:
// Возвращает длительность суток в секундах
//
// Возвращаемое значение:
// Число
//
Функция ДлительностьСутокВСекундах() Экспорт
Возврат 24 * 60 * 60;
КонецФункции
// Возвращает длительность периода в днях, включая дни дат начала и окончания
//
// Параметры:
// ДатаНачала - Дата
// ДатаОкончания - Дата
//
// Возвращаемое значение:
// Число
//
Функция ДнейВПериоде(Знач ДатаНачала, Знач ДатаОкончания, Знач ПроверятьКорректностьПериода = Ложь) Экспорт
Если ПроверятьКорректностьПериода Тогда
Возврат ?(НачалоДня(ДатаНачала) > НачалоДня(ДатаОкончания), 0, (КонецДня(ДатаОкончания) + 1 - НачалоДня(ДатаНачала)) / ДлительностьСутокВСекундах());
КонецЕсли;
Возврат (КонецДня(ДатаОкончания) + 1 - НачалоДня(ДатаНачала)) / ДлительностьСутокВСекундах();
КонецФункции
Показать
(6) Опять 2 месяца и 2 дня.
Проблема количества месяцев всем понятна. Я не знаю какого-то общепринятого правила вычисления количества месяцев в периоде.
С серединой месяца проще. Достаточно решить, куда округлять при делении на 2. Если отбрасывать дробную часть, то в високосном феврале первая половина месяца 14 дней, а вторая 15.
Проблема количества месяцев всем понятна. Я не знаю какого-то общепринятого правила вычисления количества месяцев в периоде.
С серединой месяца проще. Достаточно решить, куда округлять при делении на 2. Если отбрасывать дробную часть, то в високосном феврале первая половина месяца 14 дней, а вторая 15.
В УПП была процедура в модуле общего назначения:
// Процедура вычисляет количество лет, месяцев и дней между двумя датами
//
// Параметры
// Дата1 – дата, первая дата (более поздняя, часто текущая, стаж определяется по состоянию на эту дату)
// Дата2 – дата, вторая дата (ранняя дата, с нее начинается "течение" стажа)
// Лет – Число, в этот параметр будет записано кол-во лет между двумя датами (Дата1-Дата2)
// Месяцев – Число, в этот параметр будет записано кол-во месяцев между двумя датами (Дата1-Дата2)
// Дней – Число, в этот параметр будет записано кол-во дней между двумя датами (Дата1-Дата2)
//
Процедура РазобратьРазностьДат(Дата1, Дата2, Лет = 0, Месяцев = 0, Дней = 0) Экспорт
Лет = 0;
Месяцев = 0;
Дней = 0;
Если Дата1 > Дата2 Тогда
ВременнаяДата = Дата1;
Если День(ВременнаяДата) < День(Дата2) Тогда
Дней = (ВременнаяДата - ДобавитьМесяц(ВременнаяДата,-1))/86400;
ВременнаяДата = ДобавитьМесяц(ВременнаяДата,-1);
КонецЕсли;
Если Месяц(ВременнаяДата) < Месяц(Дата2) Тогда
ВременнаяДата = ДобавитьМесяц(ВременнаяДата,-12);
Месяцев = 12;
КонецЕсли;
Лет = Макс( Год(ВременнаяДата) - Год(Дата2), 0);
Месяцев = Макс(Месяцев + Месяц(ВременнаяДата) - Месяц(Дата2), 0);
Дней = Макс(Дней + День(ВременнаяДата) - День(Дата2), 0);
// скорректируем отображаемое значение, если "вмешалось" разное количество дней в месяцах
Если Дата2 <> (ДобавитьМесяц(Дата1,-Лет*12-Месяцев)-Дней*86400) Тогда
Дней = Дней + ((ДобавитьМесяц(Дата1,-Лет*12-Месяцев)-Дней*86400) - Дата2)/86400;
//(День(КонецМесяца(Дата2)) - День(НачалоМесяца(Дата2))) - (День(КонецМесяца(ДобавитьМесяц(Дата1,-1))) - День(НачалоМесяца(ДобавитьМесяц(Дата1,-1))));
КонецЕсли;
КонецЕсли;
КонецПроцедуры // РазобратьРазностьДат
Показать
Как вариант.
Функция РазностьДат (НачалоПериода,КонецПериода)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ВЫБОР
| КОГДА РАЗНОСТЬДАТ(&ДатаНачала, &КонецПериода, МЕСЯЦ) >= 1
| ТОГДА РАЗНОСТЬДАТ(&ДатаНачала, КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ), ДЕНЬ)
| ИНАЧЕ РАЗНОСТЬДАТ(&ДатаНачала, &КонецПериода, ДЕНЬ)
| КОНЕЦ КАК ПерваяЧастьДней,
| ВЫБОР
| КОГДА РАЗНОСТЬДАТ(&ДатаНачала, &КонецПериода, МЕСЯЦ) >= 1
| ТОГДА РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ), СЕКУНДА, 1),
| НАЧАЛОПЕРИОДА(&КонецПериода, МЕСЯЦ), МЕСЯЦ)
| ИНАЧЕ 0
| КОНЕЦ КАК МесяцевВсего,
| ВЫБОР
| КОГДА РАЗНОСТЬДАТ(&ДатаНачала, &КонецПериода, МЕСЯЦ) >= 1
| ТОГДА РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&КонецПериода, МЕСЯЦ), ДОБАВИТЬКДАТЕ(&КонецПериода, ДЕНЬ, 1), ДЕНЬ)
| ИНАЧЕ 0
| КОНЕЦ КАК ВтораяЧастьДней
|ПОМЕСТИТЬ ВТРазницаДат
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| ВЫБОР
| КОГДА ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней > 31
| ТОГДА (ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней) - 31
| ИНАЧЕ ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней
| КОНЕЦ КАК Дней,
| ВЫБОР
| КОГДА ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней >= 31
| ТОГДА ВТРазницаДат.МесяцевВсего + 1
| ИНАЧЕ
| ВТРазницаДат.МесяцевВсего
| КОНЕЦ КАК Месяцев
|ИЗ
| ВТРазницаДат КАК ВТРазницаДат";
Запрос.УстновитьПараметр("ДатаНачала",НачалоПериода);
Запрос.УстновитьПараметр("КонецПериода",КонецПериода);
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
Возврат Новый Структура ("Месяцев,Дней",Выборка.Месяцев,Выборка.Дней)
КонецФункции
Показать
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот