Разница между датами

22.07.26

Разработка - Универсальные функции

Расчёт разницы между датами с корректным склонением и учётом високосных годов. Превращение разницы дат в текст. Код открыт.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Разница между датами
.epf 8,29Kb
1 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

Обработка «Расчёт разницы между датами с корректным склонением и учётом високосных годов»

 

Назначение

Обработка предназначена для расчёта разницы между двумя датами в понятном человеку формате: с разбивкой на годы, месяцы, дни, часы, минуты и секунды. Результат выводится с корректным склонением слов («год/года/лет» и т. д.) по правилам русского языка, а учёт високосных лет и разной длины месяцев обеспечивается за счёт работы с календарём платформы 1С.


Основные возможности

  • Точный расчёт разницы: вычисляет разницу в секундах, затем преобразует её в дни, часы, минуты, секунды.
  • «Человеческая» разбивка: отдельно формирует представление интервала в годах, месяцах и днях, корректно учитывая реальную длину месяцев и високосные годы (через функцию ДобавитьМесяц).
  • Корректное склонение единиц измерения: автоматически подставляет «год», «года» или «лет» с учётом исключений для чисел 11–19.
  • Учёт направления разницы: если конечная дата меньше начальной, в начале результата добавляется знак «−».
  • Демонстрационный режим: встроенная процедура Рандом() генерирует случайные интервалы дат для быстрой проверки работы обработки.
  • Отображение полного числа дней: в скобках выводится точное количество полных дней между датами — это полезно для сверки и отчётности.

Особенности реализации

  • Серверная функция ПолучитьРазностьДат выполняет основные вычисления, включая нормализацию порядка дат и расчёт как точной, так и «человеческой» разницы.
  • Клиентская функция СклонитьГод реализует логику склонения по правилам русского языка: обрабатывает исключения для чисел 11–19 и корректно формирует окончания в зависимости от последней цифры.
  • Процедура ОбновитьРазность формирует итоговую строку вывода, пропуская нулевые значения для лет и месяцев (если нет остатка), но всегда показывая дни, если они есть или являются единственной единицей измерения.
  • Генерация тестовых данных (Рандом) позволяет быстро проверить обработку на разных интервалах — от нескольких часов до 50 лет.

Сценарии использования

  • В отчётах и формах документов: для наглядного отображения длительности периодов (например, «срок просрочки», «длительность проекта», «возраст объекта»).
  • Для пользовательских интерфейсов: когда важно показать разницу в привычном формате («2 года 3 месяца 5 дней»), а не просто в днях или секундах.
  • При тестировании и демонстрации: встроенный генератор случайных дат упрощает проверку корректности расчётов на разных временных интервалах, включая переходы через високосные годы.
  • Для интеграции в другие обработки: функцию ПолучитьРазностьДат можно вынести в общий модуль и использовать в других частях конфигурации.

Технические требования

  • Платформа: 1С:Предприятие 8.3 и выше.
  • Конфигурация: любая, поддерживающая управляемые формы.
  • Зависимости: не требуются.

Важные нюансы

  • Учёт високосных годов происходит автоматически за счёт платформенной функции ДобавитьМесяц, поэтому не требуется ручное определение високосности года.
  • Для месяцев и дней используется сокращённая форма («мес.», «дн.») — это общепринятый формат в интерфейсах 1С; склонение для них не применяется.

Проверено на следующих конфигурациях и релизах:

  • Управление торговлей, редакция 11, релизы 11.5.27.61

Вступайте в нашу телеграмм-группу Инфостарт

разница дат разность дат посчитать число дней обработка на УФ

См. также

Загрузка и выгрузка в Excel Универсальные функции Программист 1С:Предприятие 8 Россия Бесплатно (free)

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

30.10.2025    7356    Abysswalker    11    

48

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

Порой необходимо временно отключить расширение 1С, не удаляя его, чтобы не потерять данные. Но в этом случае при каждом запуске всем будет лезть уведомление о неактивном расширении, хотя очевидно, это техническая информация, которой не стоит лишний раз пугать пользователей.

14.05.2025    12505    DeerCven    15    

64

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    65164    dimanich70    87    

177

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    8670    7    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    81696    atdonya    31    

75

Универсальные функции Программист 1С:Предприятие 8 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    12547    ke.92@mail.ru    18    

68
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. V.Nikonov 130 23.07.26 09:05 Сейчас в теме
Насчёт подсчёта Лет/Дней/Часов/Секунд - кажется перебором. В крайнем случае надо разделить Функции (Дни отдельно, часы с секундами отдельно).
В функции не помешает получение структуры: "Лет,Месяцев,Дней,ВсегоСуток" и "Дней,Часов,Минут" - для использования в некоторых дополнительных вычислениях (например, для округления)...? А текстовое представление формировать из Скормленной структуры (для того масштаба, который требуется)...
4. peshitepisma 41 24.07.26 12:57 Сейчас в теме
(1)
но, часы с секундами отдельно).
В функции не помешает получение структуры: "Лет,Месяцев,Дней,ВсегоСуток" и "Дней,Часов,Минут" - для использования в некоторых дополнительных вычислениях (например, для округления)...? А текстовое представление формировать из Скормленной структуры (для того масштаба, который требуется)...


Да, вот функция через структуру, тут так и реализовано

&НаСервере
Функция ПолучитьРазностьДат(ДатаН, ДатаК)
    // Нормализуем направление, чтобы ДатаК >= ДатаН
    Если ДатаК < ДатаН Тогда
        Временная = ДатаН;
        ДатаН = ДатаК;
        ДатаК = Временная;
        Знак = "-";
    Иначе
        Знак = "";
    КонецЕсли;

    // --- 1. Точная разбивка (дни, часы, минуты, секунды) ---
    РазностьСекунды = Цел((ДатаК - ДатаН));

    ДниТочные = Цел(РазностьСекунды / 86400);
    Остаток = РазностьСекунды - ДниТочные * 86400;

    Часы = Цел(Остаток / 3600);
    Остаток = Остаток - Часы * 3600;

    Минуты = Цел(Остаток / 60);
    Секунды = Остаток - Минуты * 60;

    // --- 2. Человеческая разбивка (годы, месяцы, дни) с учётом календаря ---
    Годы = 0;
    Месяцы = 0;
    Текущая = ДатаН;

    // Добавляем полные годы (по 12 месяцев), пока не выйдем за ДатаК
    Пока ДобавитьМесяц(Текущая, 12) <= ДатаК Цикл
        Текущая = ДобавитьМесяц(Текущая, 12);
        Годы = Годы + 1;
    КонецЦикла;

    // Добавляем полные месяцы, пока не выйдем за ДатаК
    Пока ДобавитьМесяц(Текущая, 1) <= ДатаК Цикл
        Текущая = ДобавитьМесяц(Текущая, 1);
        Месяцы = Месяцы + 1;
    КонецЦикла;

    // Оставшиеся дни (между последней «полной» датой и ДатаК)
    ДниЧеловеческие = Цел((ДатаК - Текущая) / 86400);

    Возврат Новый Структура(
        "Знак, ДниТочные, Часы, Минуты, Секунды, Годы, Месяцы, ДниЧеловеческие",
        Знак, ДниТочные, Часы, Минуты, Секунды, Годы, Месяцы, ДниЧеловеческие
    );
КонецФункции
Показать
2. ckif17 23.07.26 18:27 Сейчас в теме
Вот даже не поленился зайти, Серьезно? 2500 рублей? за
РазницаЛет = Год(ДатаОкончание) - Год(ДатаНачала);
РазницаМесяцев = Месяц(ДатаОкончания)-Месяц(ДатаНачала);
РазницаДней  = День(ДатаОкончания) -День(ДатаНачала);
РазницаДнейВсего = Цел((ДатаОкончания-ДатаНачала)/60/60/24);
РазницаЧасов = Час(ДатаОкончания)-Час(ДатаНачала);
РазницаМинуты = Минута(ДатаОкончания)- Минута(ДатаНачала);
РазницаСекудны = Секунда(ДатаОкончания)-Секунда(ДатаНачала);
сколонение Лет вообще шутка что ли
ФункцияСклоненияЛет(РазницаЛет)
ДлинаРазницы = СтрДлина(Строка(РазинцаЛет));
Если ДлинаРазницы>1 тогда
Если Число(Прав(Строка(РазинцаЛет,2)>20 тогда
ЭтоНеИсключение = Истина;
Иначе
ЭтоНеИсключение=Ложь;
КонецЕсли
Если ДлинаРазницы=1 или ЭтоНеИсключение тогда
Если Число(Прав(Строка(РазинцаЛет,1))=0 тогда
Возврат "лет"
 ИначеЕсли Число(Прав(Строка(РазинцаЛет,1))=1 тогда
Возврат "год"
ИначеЕсли Число(Прав(Строка(РазинцаЛет,1))<5 тогда
Возврат "года"
Иначе
Возврат "лет"
КонецЕсли;
Иначе
Возврат "лет"
КонецЕсли;
КонецФункции
Показать

Осталось это все в одну строковую переменную сложить и все, без конфигуратора я это написал за 3 минуты, и то отвлекаясь
3. ckif17 23.07.26 19:00 Сейчас в теме
Месяцы, дни, часы, минуты и секунды чуть сложней считаются, с вычитанием из предыдущего, но все равно не сложно. високонсный год или нет даже думать не надо День(КонецМесяца(ДобавитьМесяц(ДатаОкончания,-1) и все
5. peshitepisma 41 24.07.26 13:10 Сейчас в теме
(3) 2500 за это? Я думаю это много, раньше же за 1 стартмани было? Возможно у тебя не купленная подписка

В твоём коде есть несколько критических проблем. Для разницы в годах/месяцах нужна полноценная логика с учётом переполнения (как в «календарной» разнице).В коде много опечаток (РазинцаЛет вместо РазницаЛет, неправильные скобки), а логика проверки «последних двух цифр > 20» реализована с ошибками - в условии Число(Прав(Строка(РазинцаЛет,2)>20 пропущена закрывающая скобка. Кроме того, функция не обрабатывает отрицательные значения и ноль.

Если нужна функция склонения возьми эту:

&НаСервере
Функция СклонитьГоды(Количество)
    
    Количество = Цел(Количество);
    Если Количество < 0 Тогда
        Количество = -Количество;
    КонецЕсли;
    
    ЧислоДляПроверки = Количество;
    ПоследниеДвеЦифры = ЧислоДляПроверки % 100;
    ПоследняяЦифра = ЧислоДляПроверки % 10;
    
    // Исключения 11–19 всегда «лет»
    Если ПоследниеДвеЦифры >= 11 И ПоследниеДвеЦифры <= 19 Тогда
        Возврат "лет";
    КонецЕсли;
    
    // Остальные случаи смотрим по последней цифре
    Если ПоследняяЦифра = 1 Тогда
        Возврат "год";
    ИначеЕсли ПоследняяЦифра >= 2 И ПоследняяЦифра <= 4 Тогда
        Возврат "года";
    Иначе
        Возврат "лет";
    КонецЕсли;
    
КонецФункции
Показать
6. ckif17 26.07.26 21:56 Сейчас в теме
Да, упустил момент что у меня нет подписки. Опечатки в тексте, так как, как говорил, писал без конфигуратора и с телефона. Если уж полностью с учетом всего текст модуля будет такой :
Перем ТаблицаСклонения;
Функция ПолучитьРазницуДат(НачалоПериода,КонецПериода,ВыводитьНулевыеЗначения) Экспорт 
	СоздатьТаблицуСклонения(); 
	РазницаЛет = ПолучитьРазницу(Год(НачалоПериода),Год(КонецПериода);
	РазницаМесяцев = ПолучитьРазницу(Месяц(НачалоПериода),Месяц(КонецПериода,12,РазницаЛет);
	РазницаДней = ПолучитьРазницу(День(НачалоПериода),День(КонецПериода),День(КонецМесяца(ДобавитьМесяц(КонецПериода))),РазницаМесяцев); 
	РазницаЧасов = ПолучитьРазницу(Час(НачалоПериода),Час(КонецПериода),23,РазницаДней); 
	РазницаМинут = ПолучитьРазницу(Минута(НачалоПериода),Минута(КонецПериода),59,РазницаЧасов);
	РазницаСекунд = ПолучитьРазницу(Секунда(НачалоПериода),Секунда(КонецПериода),59,РазницаМинут); 
	РазницаДнейВсего	= Цел((КонецПериода-НачалоПериода)/60/60/24);
	Разница =""+?(ВыводитьНулевыеЗначения или РазницаЛет>0,РазницаЛет+" "+ПолучитьСклонениеЕдиницыВремени("Год",РазницаЛет)+" ","")
	?(ВыводитьНулевыеЗначения или РазницаМесяцев>0,РазницаМесяцев+" "+ПолучитьСклонениеЕдиницыВремени("месяц",РазницаМесяцев)+" ","")+
	?(ВыводитьНулевыеЗначения или РазницаДней>0,РазницаДней+" "+ПолучитьСклонениеЕдиницыВремени("день",РазницаДней)+" ","")+
	?(ВыводитьНулевыеЗначения или РазницаЧасов>0,РазницаЧасов+" "+ПолучитьСклонениеЕдиницыВремени("час",РазницаЧасов)+" ","")+
	?(ВыводитьНулевыеЗначения или РазницаМинут>0,РазницаМинут+" "+ПолучитьСклонениеЕдиницыВремени("минута",РазницаМинут)+" ","")+
	?(ВыводитьНулевыеЗначения или РазницаСекунд>0,РазницаСекунд+" "+ПолучитьСклонениеЕдиницыВремени("секунда",РазницаСекунд)+" ","")+
	?(ВыводитьНулевыеЗначения или РазницаДнейВсего>0,"("+РазницаДнейВсего+" "+ПолучитьСклонениеЕдиницыВремени("день",РазницаДнейВсего)+")","");
	Возврат Разница;
КонецФункции
Функция ПолучитьРазницу(НачальноеЗначение,КонечноеЗначение,МаксЗначение=Неопределено,ЗначениеПредыдущего=Неопределено)
	Разница = КонечноеЗначение-НачальноеЗначение;
	Если Разница<0 тогда
		ЗначениеПредыдущего=ЗначениеПредыдущего-1;
		Возврат МаксЗначение+Разница;
	Иначе
		Возврат Разница;
	КонецЕсли;
КонецФункции
Функция СоздатьТаблицуСклонения()
	ТаблицаСклонения= Новый ТаблицаЗначений;
	ТаблицаСклонения.Колонки.Добавить("ЕдиницаВремени");
	ТаблицаСклонения.Колонки.Добавить("ЗначениеДля2_4");
	ТаблицаСклонения.Колонки.Добавить("ЗначениеДляОстальное");
	ДобавитьСтрокуВТаблицуСклонения(ТаблицаСклонения,"год","года","лет");
	ДобавитьСтрокуВТаблицуСклонения(ТаблицаСклонения,"месяц","месяца","месяцев"); 
	ДобавитьСтрокуВТаблицуСклонения(ТаблицаСклонения,"день","дня","дней");
	ДобавитьСтрокуВТаблицуСклонения(ТаблицаСклонения,"час","часа","часов");
	ДобавитьСтрокуВТаблицуСклонения(ТаблицаСклонения,"минута","минуты","минут");
	ДобавитьСтрокуВТаблицуСклонения(ТаблицаСклонения,"секунда","секунды","секунд");
КонецФункции 
Процедура ДобавитьСтрокуВТаблицуСклонения(ТаблицаСклонения,ЕдиницаВремени,ЗначениеДля2_4,ЗначениеДляОстальное) 
	НоваяСтрока							= ТабилцаСклонения.Добавить;
	НоваяСтрока.ЕдиницаВремени			= ЕдиницаВремени;
	НоваяСтрока.ЗначениеДля2_4			= ЗначениеДля2_4;
	НоваяСтрока.ЗначениеДляОстальное	= ЗначениеДляОстальное;
КонецПроцедуры
Функция ПолучитьСклонениеЕдиницыВремени(ЕдиницаВремени,ЗначениеРазницы)
	ПоследниеДвеЦифры = ЗначениеРазницы % 100;
    ПоследняяЦифра = ЗначениеРазницы % 10;
    СтрокаСклонения = ТабилцаСклонения.Найти(ЕдиницаВремени,"ЕдиницаВремени")
      Если ПоследниеДвеЦифры >= 11 И ПоследниеДвеЦифры <= 19 Тогда
        Возврат СтрокаСклонения.ЗначениеДляОстальное;
    КонецЕсли;
    
    // Остальные случаи смотрим по последней цифре
    Если ПоследняяЦифра = 1 Тогда
        Возврат СтрокаСклонения.ЕдиницаВремени;
    ИначеЕсли ПоследняяЦифра >= 2 И ПоследняяЦифра <= 4 Тогда
        Возврат СтрокаСклонения.ЗначениеДля2_4;
    Иначе
        Возврат СтрокаСклонения.ЗначениеДляОстальное;
    КонецЕсли;
КонецФункции
Показать
7. ckif17 27.07.26 13:26 Сейчас в теме
(6) Единственное, все же для часа надо 24, а для минут и секунд 60, а для дня не дописал что -1 месяц добавляем, должно быть День(КонецМесяца(ДобавитьМесяц(КонецПериода,-1)))
Для отправки сообщения требуется регистрация/авторизация