Имя: Пароль:
1C
1С v8
Как посчитать разность дат?
,
0 Nzzzz
 
20.08.19
11:05
Здравствуйте! Нужно посчитать стаж в ЗУП 2.5
Был такой код изначально:


    Лет = 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))));
        КонецЕсли;
    КонецЕсли;


Но он не правильно счиатает. Было найдено такое решение:

МассивДат = РазностьДат(Дата2,Дата1);
    Если Прав(МассивДат[0], 1) = "1"
        ИЛИ Прав(МассивДат[0], 1) = "2"
        ИЛИ Прав(МассивДат[0], 1) = "3"
        ИЛИ Прав(МассивДат[0], 1) = "4"
        Тогда п = " г. ";
    Иначе п = " л. ";
    КонецЕсли;
    
    Стаж = Строка(МассивДат[0]) + п + Строка(МассивДат[1]) + " м. " + Строка(МассивДат[2]) + " д.";


Но у меня ошибка:

{ВнешняяОбработка.СправкаПоСтажу.МодульОбъекта(127,17)}: Процедура или функция с указанным именем не определена (РазностьДат)
       МассивДат = <<?>>РазностьДат(Дата2,Дата1); (Проверка: Толстый клиент (обычное приложение))


Кто нибудь знает, есть ли в ЗУП 2.5 какая нибудь такая функция?
1 dezss
 
20.08.19
11:12
Дата1-Дата2.
Будет в секундах. Дальше объяснять?
2 Андрюха
 
20.08.19
11:17
(0) В запросе удобно рассчитывать
3 Nzzzz
 
20.08.19
11:19
(1) Смысл понятен, но это уже будет похоже на первый вариант моего кода
4 dezss
 
20.08.19
11:24
(3) Ну отсюда и копай, если не хочешь запросами. Запросами там тоже будут нюансы.
Все что тебе нужно, это определить сколько лет прошло, потом определить сколько из них високосных.
И последнее, это определить количество месяцев-дней после первой даты и до последней.
5 Said_We
 
20.08.19
12:07
6 dezss
 
20.08.19
12:29
Стало интересно. Набросал. Вот что получилось.

&НаКлиентеНаСервереБезКонтекста
Функция Високосный(мГод)
     Возврат ?(Цел(мГод/4) = мГод,Истина,Ложь);
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция КолВоВисок(Знач Дата1, Знач Дата2)
    Год2 = Год(Дата2)-1;
    Год1 = Год(Дата1)+1;
    Рез = 0;
    Для й=Год1 По Год2 Цикл
        Если Високосный(й) Тогда
            Рез = Рез + 1;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Рез;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ВычитаемЛет(Знач Дата1, Знач Дата2)
    Рез = 0;
    Если Месяц(Дата1) > Месяц(Дата2) Тогда
        Рез = 1;
    ИначеЕсли Месяц(Дата1) = Месяц(Дата2) И День(Дата1) > День(Дата2) Тогда
        Рез = 1;
    КонецЕсли;
    
    Возврат Рез;
КонецФункции

&НаКлиенте
Процедура Команда1(Команда)
    
    мГод = 0;
    мМесяц = 0;
    мДень = 0;
    
    мДеньВСек = 60*60*24;
    мГодВСек = мДеньВСек*365;
    
    Разн = Дата2 - Дата1;
    
    Если Разн >= мГодВСек Тогда
        мГод = Год(Дата2) - Год(Дата1) - ВычитаемЛет(Дата1,Дата2);
        Висок = КолВоВисок(Дата1,Дата2);
        Разн = Разн - мГод*мГодВСек - Висок*мДеньВСек;
    КонецЕсли;
    
    Мес1 = Месяц(Дата1);
    Мес2 = Месяц(Дата2);
    
    Тек = Мес1;//(Мес1 + 1) - Цел((Мес1 + 1)/12)*12;
    Если Тек < Мес2 Тогда
        Прямой = Истина;
    Иначе
        Прямой = Ложь;
    КонецЕсли;
    
    Если Мес1 <> Мес2 Тогда
        Пока Истина Цикл
            ДнейВМес = День(КонецМесяца(Дата(2001,Тек,1)));
            Разн1 = Разн - ДнейВМес*мДеньВСек;
            Если Разн1 < 0 Тогда
                Прервать;
            КонецЕсли;
            Разн = Разн1;
            мМесяц = мМесяц + 1;
            Если Не Прямой Тогда
                Если Тек = 12 Тогда
                    Прямой = Истина;
                    Тек = 0;
                КонецЕсли;
            КонецЕсли;
            Тек = Тек + 1;
        КонецЦикла;
    КонецЕсли;
    
    Если Високосный(Год(Дата1)) И Мес1 <=2 Тогда
        Разн = Разн - мДеньВСек;
    КонецЕсли;
    
    Если Високосный(Год(Дата2)) И Мес2 >2 Тогда
        Разн = Разн - мДеньВСек;
    КонецЕсли;
    
    мДень = Окр(Разн/мДеньВСек);
    
    Разн = Разн - мДень*мДеньВСек;
    
    Сообщить("" + мГод + " . " + мМесяц + " . " + мДень + "___" + Разн + " < " + мДеньВСек);
КонецПроцедуры
7 Said_We
 
20.08.19
12:38
(6) Вот что с кодом управляемые формы делают.....
Если ...
    Пока ....
        Если ...
            Если ...
...
Ничего не понял...
8 Grekos2
 
20.08.19
12:40
а в чем может быть проблема если считать запросом ?
9 Said_We
 
20.08.19
12:42
(8) Да без разницы чем считать. Запрос удобнее если надо посчитать сразу много пар ДатаС и ДатаПо.
10 dezss
 
20.08.19
12:46
(7) э...а при чем тут управляемые формы?
11 dezss
 
20.08.19
12:50
(5) Там есть косяк
ВЫБРАТЬ
    ДАТАВРЕМЯ(2009, 9, 30),
    ДАТАВРЕМЯ(2010, 3, 1)

30.09.2009 0:00:00    01.03.2010 0:00:00    0    5    -1
12 dezss
 
20.08.19
12:52
(11) +
31.12.2006 0:00:00    01.03.2010 0:00:00    3    2    -2
13 Said_We
 
20.08.19
13:02
(11) (12) - до конца дочитал?
14 Said_We
 
20.08.19
13:03
(10) Ну как причем?....
Зачем вообще цикл для решения такой задачи? Да еще цикл "Пока ИСТИНА"...
15 SSSSS_AAAAA
 
20.08.19
13:31
(0) "Нужно посчитать стаж в ЗУП 2.5"
"есть ли в ЗУП 2.5 какая нибудь такая функция"

Точно там что-то было. Кстати, самодеятельность в алгоритме расчета этого стажа чревата, ибо этот алгоритм установлен законодательно. Потому не стОит изгаляться с запросами и т.д.
16 Serg_1960
 
20.08.19
14:07
Это из УПП, из общего модуля начислений по больничному листу:

    ЛетСтажа    = 0;
    МесяцевСтажа= 0;
    ДнейСтажа    = 0;
    ДатаНепрерывногоСтажа = ПроведениеРасчетов.ПолучитьНачалоСтажаДляБольничногоЛиста(ДатаСобытия, Сотрудник.Физлицо, Организация);
    Если ЗначениеЗаполнено(ДатаНепрерывногоСтажа) Тогда
        ОбщегоНазначенияЗК.РазобратьРазностьДат(ДатаСобытия, ДатаНепрерывногоСтажа, ЛетСтажа, МесяцевСтажа, ДнейСтажа);
    КонецЕсли;
17 Serg_1960
 
20.08.19
14:11
Алгоритм РазобратьРазностьДат() указан в нулевом посту. Круг замкнулся :)
18 dezss
 
20.08.19
14:16
(13) Каюсь, не до конца.
(14) Ну вот так, при чем тут именно УФ?)
В прод, я такое решение конечно не пущу, просто быстро набросал то, что поможет посчитать.
Понятно, что надо быть аккуратным с циклом Пока Истина, но чем он тебе так не нравится?
AdBlock убивает бесплатный контент. 1Сергей