Функция возвращающая разность дат в днях и месяцах.УТ 11.4

1. Az18011993 18.11.21 10:26 Сейчас в теме
Добрый день,уважаемые форумчане!
Нужна функция,которая бы возвращала разницу в днях и месяцах между датами.
Нашел вот такой пример:
РазницаВДнях = (НачалоДня(ДатаОкончания) - НачалоДня(ДатаНачала)) / (60 * 60 * 24);

Но от части он мне не совсем подходит,т.к. например если мне вернется число 28 - 31 то это уже месяц:)
Может кто сталкивался с такой задачей?
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
4. homer_ 78 18.11.21 10:51 Сейчас в теме
(1) вот пример
30.12.2021 - 28.02.2022
По вашим размышлениям какая разница
23. sssss_aaaaa_2011 07.09.22 16:36 Сейчас в теме
(1)
Может кто сталкивался с такой задачей?
Все сталкивались с такой задачей.
И до некоторых очень туго доходит, что НЕТ универсального единого способа расчета разницы в единицах нефиксированного размера.
Вам в каких месяцах нужна разница? Январях? Апрелях? Или может февралях? А как насчет високосных февралей?
Из-за этого существуют свои собственные алгоритмы расчета таких сроков для конкретных назначений. Например, для стажей работы их несколько штук в зависимости от того какой конкретно стаж надо посчитать.
Потому не пытайтесь найти черную кошку в черной комнате, ее там нет, и пишите алгоритм, который требуется вашим клиентам и не занимайтесь при этом отсебятиной. Если, конечно, не подходит один из уже существующих.
26. sssss_aaaaa_2011 07.09.22 17:02 Сейчас в теме
(1)И посыпались очередные попытки что-то написать совершенно не зная какой именно алгоритм расчета нужен топикстартеру. И каждый лепит алгоритм по своим, никому другому не известным умолчаниям, которые, однако, могут ну никак не совпадать с умолчаниями, подразумеваемыми тем же топикстатртером. Он и сам то может не о всех условиях расчета знает, но народ строчит...
Еще раз - какой месяц используем? Усредненный? Фиксированный 30 дней? Как обсчитывать граничные месяцы? И т.д.
27. sssss_aaaaa_2011 07.09.22 17:13 Сейчас в теме
(1)И еще по поводу запрета на отсебятину.
Правила многих таких расчетов закреплены законодательно. В чем каждый может убедиться на примере трудовых, вредных и прочих пенсионных стажей.
2. user1278383 4 18.11.21 10:38 Сейчас в теме
РазностьДат (DateDiff)
Функция предназначена для получения разницы между двумя датами.
Синтаксис:
РазностьДат(Выражение1 , Выражение2 , ТипРазности)
Параметры:
Выражение1 - тип Дата. Вычитаемая дата;
Выражение2 - тип Дата. Исходная дата;
ТипРазности - тип Строка. Содержит одно из значений:
Секунда;
Минута;
Час;
День;
Месяц;
Квартал;
Год.
Пример:
РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2002, 10, 12, 10, 15, 34),
ДАТАВРЕМЯ(2002, 10, 14, 9, 18, 06), "ДЕНЬ")
Результат:
2
3. VZyryanov 18.11.21 10:43 Сейчас в теме
Из ЗУП 3.1:
// Возвращает длительность суток в секундах
//
// Возвращаемое значение:
//		Число
//
Функция ДлительностьСутокВСекундах() Экспорт
	
	Возврат 24 * 60 * 60;
	
КонецФункции

// Возвращает длительность периода в днях, включая дни дат начала и окончания
//
// Параметры:
//		ДатаНачала		- Дата
//		ДатаОкончания	- Дата
//
// Возвращаемое значение:
//		Число
//
Функция ДнейВПериоде(Знач ДатаНачала, Знач ДатаОкончания, Знач ПроверятьКорректностьПериода = Ложь) Экспорт
	
	Если ПроверятьКорректностьПериода Тогда
		Возврат ?(НачалоДня(ДатаНачала) > НачалоДня(ДатаОкончания), 0, (КонецДня(ДатаОкончания) + 1 - НачалоДня(ДатаНачала)) / ДлительностьСутокВСекундах());
	КонецЕсли;
	
	Возврат (КонецДня(ДатаОкончания) + 1 - НачалоДня(ДатаНачала)) / ДлительностьСутокВСекундах();
	
КонецФункции
Показать
10. Az18011993 18.11.21 11:31 Сейчас в теме
(3)У меня разница между датами 05.08.2021 и 02.08.2021 выдает 4 дня...Что-то тут не так:С
24. sssss_aaaaa_2011 07.09.22 16:52 Сейчас в теме
(10)Не оговорено не/включение концевых дат расчет. Топикстартер еще не понимает, что для расчета сроков это одно из важнейших условий.
5. VZyryanov 18.11.21 10:55 Сейчас в теме
6. homer_ 78 18.11.21 11:10 Сейчас в теме
(5) приведите ваш расчет, меня ваши расчеты в ступор вогнали))
я вам более сложный расчет сейчас дам) а вот так
15.12.2021 - 15.02.2022. что вы будете считать серединой месяца) если будет високосный год
7. Az18011993 18.11.21 11:11 Сейчас в теме
(6)високосный год вроде в 1С не учитывается...Хотя я могу ошибаться.
9. homer_ 78 18.11.21 11:20 Сейчас в теме
(7) Все считается, но вы так и не привели пример как вы вышли на 2 мес 2 дня
ваш механизм утопия т.к. или считается месяца или дни. А если вам надо месяца и дни то или вы придумаете свой механизм расчета или берете общепринятые механизмы (дни делим на 30)
13. VZyryanov 18.11.21 11:38 Сейчас в теме
(6) Опять 2 месяца и 2 дня.
Проблема количества месяцев всем понятна. Я не знаю какого-то общепринятого правила вычисления количества месяцев в периоде.
С серединой месяца проще. Достаточно решить, куда округлять при делении на 2. Если отбрасывать дробную часть, то в високосном феврале первая половина месяца 14 дней, а вторая 15.
14. Az18011993 18.11.21 11:40 Сейчас в теме
(13)Если я правильно понял,то в 1С приятно количество дней делить на 30
25. sssss_aaaaa_2011 07.09.22 16:54 Сейчас в теме
(13)
Я не знаю какого-то общепринятого правила вычисления количества месяцев в периоде.
И не только вы. Ибо его НЕТ.

(13)
Достаточно решить
А вот это уже часть техзадания на реализацию конкретного алгоритма расчета. И решать тут имеет право только заказчик.
8. lejik 18.11.21 11:17 Сейчас в теме
В УПП была процедура в модуле общего назначения:
// Процедура вычисляет количество лет, месяцев и дней между двумя датами
//
// Параметры
//  Дата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))));
		КонецЕсли;
		
	КонецЕсли;

КонецПроцедуры	// РазобратьРазностьДат
Показать
12. Az18011993 18.11.21 11:37 Сейчас в теме
(8)А что она возвращает то?Мне нужна функция,а не процедура...
15. Az18011993 18.11.21 11:47 Сейчас в теме
(8)Она походу не округляет дни:С
У меня есть дата 02.08.2021 09:49:17 и есть дата 05.08.2021 00:00:00
Прикрепленные файлы:
16. lejik 18.11.21 12:06 Сейчас в теме
(15) Если надо учитывать еще и время, тогда подправить чуть логику в процедуре.
17. Az18011993 18.11.21 12:07 Сейчас в теме
(16)А если обнулять время через метод НачалоДня?
18. lejik 18.11.21 12:18 Сейчас в теме
(17) Как вариант. Или делать Окр(Дней, 0, Окр15как10)
19. VZyryanov 18.11.21 14:44 Сейчас в теме
(8) У меня эта процедура УПП выдает:
28.02.2021 - 15.03.2021 - 15 дней.
28.02.2021 - 28.03.2021 - 1 месяц, 0 дней.
28.02.2021 - 31.03.2021 - тоже 1 месяц, 0 дней.
11. homer_ 78 18.11.21 11:36 Сейчас в теме
(5) по ваше логике если я уменьшу с лева и справа дни то ни должно поменяться ваше значение 2 м 2 д

30.12.2021 - 28.02.2022 отниму 14 дней
итого
16.12.2021 - 14.02.2022
и как тут получается 2 мес и 2 дня
20. vadim1011985 100 18.11.21 22:35 Сейчас в теме
Как вариант.
Функция РазностьДат (НачалоПериода,КонецПериода)

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ
|	ВЫБОР
|		КОГДА РАЗНОСТЬДАТ(&ДатаНачала, &КонецПериода, МЕСЯЦ) >= 1
|			ТОГДА РАЗНОСТЬДАТ(&ДатаНачала, КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ), ДЕНЬ)
|		ИНАЧЕ РАЗНОСТЬДАТ(&ДатаНачала, &КонецПериода, ДЕНЬ)
|	КОНЕЦ КАК ПерваяЧастьДней,
|	ВЫБОР
|		КОГДА РАЗНОСТЬДАТ(&ДатаНачала, &КонецПериода, МЕСЯЦ) >= 1
|			ТОГДА РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ), СЕКУНДА, 1), 
|   НАЧАЛОПЕРИОДА(&КонецПериода, МЕСЯЦ), МЕСЯЦ)
|		ИНАЧЕ 0
|	КОНЕЦ КАК МесяцевВсего,
|	ВЫБОР
|		КОГДА РАЗНОСТЬДАТ(&ДатаНачала, &КонецПериода, МЕСЯЦ) >= 1
|			ТОГДА РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(&КонецПериода, МЕСЯЦ), ДОБАВИТЬКДАТЕ(&КонецПериода, ДЕНЬ, 1), ДЕНЬ)
|		ИНАЧЕ 0
|	КОНЕЦ КАК ВтораяЧастьДней
|ПОМЕСТИТЬ ВТРазницаДат
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
|	ВЫБОР
|		КОГДА ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней > 31
|			ТОГДА (ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней) - 31
|		ИНАЧЕ ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней
|	КОНЕЦ КАК Дней,
|	ВЫБОР
|		КОГДА ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней >= 31
|			ТОГДА ВТРазницаДат.МесяцевВсего + 1
|		ИНАЧЕ
|				ВТРазницаДат.МесяцевВсего 
|	КОНЕЦ КАК Месяцев
|ИЗ
|	ВТРазницаДат КАК ВТРазницаДат"; 

Запрос.УстновитьПараметр("ДатаНачала",НачалоПериода);
Запрос.УстновитьПараметр("КонецПериода",КонецПериода);

Выборка = Запрос.Выполнить().Выбрать();

Выборка.Следующий();

Возврат Новый Структура ("Месяцев,Дней",Выборка.Месяцев,Выборка.Дней)

КонецФункции
Показать
21. vadim1011985 100 19.11.21 01:34 Сейчас в теме
Немного неверно указал условие во втором запросе

вместо

КОГДА ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней > 31


Нужно
КОГДА ВТРазницаДат.ПерваяЧастьДней + ВТРазницаДат.ВтораяЧастьДней >= 31
22. dialogsoft 73 07.09.22 16:15 Сейчас в теме
УстановитьПараметр - у 20
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот