1С 8.3 Разность Дат
Данные > Примеры кода 1С > 1С 8.3 Дата и время
Перейти в основной раздел:

Вычисляет разницу между датами в указанных периодах (аналог функции языка запросов):
// Возвращает структуру множителей для различных типов периодов.
// Положительные значения - для месячных типов (добавляются через ДобавитьМесяц),
// Отрицательные - для временных (добавляются через вычитание секунд).
//
// Возвращаемое значение:
// Структура - содержит множители для всех поддерживаемых типов периодов
Функция МножителиТиповПериодов() Экспорт
Сутки = 24 * 60 * 60;
Множители = Новый Структура();
Множители.Вставить("Год", 12);
Множители.Вставить("Полугодие", 6);
Множители.Вставить("Квартал", 3);
Множители.Вставить("Месяц", 1);
Множители.Вставить("Декада", -10 * Сутки);
Множители.Вставить("Неделя", -7 * Сутки);
Множители.Вставить("День", -1 * Сутки);
Множители.Вставить("Час", -60 * 60);
Множители.Вставить("Минута", -60);
Множители.Вставить("Секунда", -1);
Возврат Множители;
КонецФункции
// Поддерживаются как месячные периоды (год, квартал, месяц), так и временные (дни, часы и т.д.).
//
// Параметры:
// ВычитаемаяДата - Дата - дата, которую вычитаем
// ИсходнаяДата - Дата - дата, из которой вычитаем
// ТипПериода - Строка - имя типа периода ("Год", "Квартал", "День" и т.д.), регистр не важен
//
// Возвращаемое значение:
// Число - разница между датами в указанных периодах (ИсходнаяДата - ВычитаемаяДата)
//
// Исключения:
// - Если тип периода не поддерживается
Функция РазностьДат(Знач ВычитаемаяДата, Знач ИсходнаяДата, Знач ТипПериода) Экспорт
// Нормализуем регистр названия типа периода
ТипПериода = ВРег(ТипПериода);
// Получаем множители для всех типов периодов
Множители = МножителиТиповПериодов();
// Проверяем поддержку указанного типа периода
Если Не Множители.Свойство(ТипПериода) Тогда
ВызватьИсключение "Неподдерживаемый тип периода: " + ТипПериода;
КонецЕсли;
// Для месячных периодов используем расчет через месяцы
Если Множители[ТипПериода] > 0 Тогда
Возврат Цел((Год(ИсходнаяДата) * 12 + Месяц(ИсходнаяДата)) / Множители[ТипПериода]) -
Цел((Год(ВычитаемаяДата) * 12 + Месяц(ВычитаемаяДата)) / Множители[ТипПериода]);
// Для временных периодов используем расчет через секунды
Иначе
РазницаВСекундах = ИсходнаяДата - ВычитаемаяДата;
Возврат Цел(РазницаВСекундах / -Множители[ТипПериода]);
КонецЕсли;
КонецФункции
// Положительные значения - для месячных типов (добавляются через ДобавитьМесяц),
// Отрицательные - для временных (добавляются через вычитание секунд).
//
// Возвращаемое значение:
// Структура - содержит множители для всех поддерживаемых типов периодов
Функция МножителиТиповПериодов() Экспорт
Сутки = 24 * 60 * 60;
Множители = Новый Структура();
Множители.Вставить("Год", 12);
Множители.Вставить("Полугодие", 6);
Множители.Вставить("Квартал", 3);
Множители.Вставить("Месяц", 1);
Множители.Вставить("Декада", -10 * Сутки);
Множители.Вставить("Неделя", -7 * Сутки);
Множители.Вставить("День", -1 * Сутки);
Множители.Вставить("Час", -60 * 60);
Множители.Вставить("Минута", -60);
Множители.Вставить("Секунда", -1);
Возврат Множители;
КонецФункции
// Поддерживаются как месячные периоды (год, квартал, месяц), так и временные (дни, часы и т.д.).
//
// Параметры:
// ВычитаемаяДата - Дата - дата, которую вычитаем
// ИсходнаяДата - Дата - дата, из которой вычитаем
// ТипПериода - Строка - имя типа периода ("Год", "Квартал", "День" и т.д.), регистр не важен
//
// Возвращаемое значение:
// Число - разница между датами в указанных периодах (ИсходнаяДата - ВычитаемаяДата)
//
// Исключения:
// - Если тип периода не поддерживается
Функция РазностьДат(Знач ВычитаемаяДата, Знач ИсходнаяДата, Знач ТипПериода) Экспорт
// Нормализуем регистр названия типа периода
ТипПериода = ВРег(ТипПериода);
// Получаем множители для всех типов периодов
Множители = МножителиТиповПериодов();
// Проверяем поддержку указанного типа периода
Если Не Множители.Свойство(ТипПериода) Тогда
ВызватьИсключение "Неподдерживаемый тип периода: " + ТипПериода;
КонецЕсли;
// Для месячных периодов используем расчет через месяцы
Если Множители[ТипПериода] > 0 Тогда
Возврат Цел((Год(ИсходнаяДата) * 12 + Месяц(ИсходнаяДата)) / Множители[ТипПериода]) -
Цел((Год(ВычитаемаяДата) * 12 + Месяц(ВычитаемаяДата)) / Множители[ТипПериода]);
// Для временных периодов используем расчет через секунды
Иначе
РазницаВСекундах = ИсходнаяДата - ВычитаемаяДата;
Возврат Цел(РазницаВСекундах / -Множители[ТипПериода]);
КонецЕсли;
КонецФункции
Разность дат как в запросе в 1С 8.3 от Сергей (ildarovich):
// Как в языке запросов
Функция РазностьДат(ДатаНач, ДатаКон, Период) Экспорт
Функция РазностьДат(ДатаНач, ДатаКон, Период) Экспорт
Шаг = Новый Структура("Год, Квартал, Месяц, Неделя, День, Час, Минута, Секунда", 12, 3, 1, -604800, -86400, -3600, -60, -1);
Возврат Цел(?(Шаг[Период] > 0, Год(ДатаКон) * 12 + Месяц(ДатаКон) - 1, '00010101' - ДатаКон) / Шаг[Период])
- Цел(?(Шаг[Период] > 0, Год(ДатаНач) * 12 + Месяц(ДатаНач) - 1, '00010101' - ДатаНач) / Шаг[Период]);
КонецФункции
Разность дат в 1С 8.3 (от user654641_yaga_m Геннадий Якименко):
// Оригинал статьи: https://infostart.ru/1c/articles/2004076/
// Страничка автора: https://infostart.ru/profile/654641/
Функция РазностьДат2(ДатаНач, ДатаПо, ДатаДо)
Если ДатаПо <> Дата('00010101') Тогда
ПеремДата = ДатаПо;
ДеньКоррекции = 3600*24; //для корректировки даты ПО
ИначеЕсли ДатаДо <> Дата('00010101') Тогда
ПеремДата = ДатаДо;
ДеньКоррекции = 0;
Иначе
НовСообщ = Новый СообщениеПользователю;
НовСообщ.Текст = "Выберите одну дату";
НовСообщ.Сообщить();
КонецЕсли;
РазницаДатыС = День(КонецМесяца(ДатаНач)) - День(ДатаНач);
КонМесДатыС = КонецМесяца(ДатаНач);
Если ПеремДата >= ДатаНач Тогда
ВремГод = 0; ВремМес = 0; ВремДней = 0;
НоваяДата = ДобавитьМесяц(КонМесДатыС, 12);
Пока НоваяДата <= ПеремДата + ДеньКоррекции Цикл
ВремГод = ВремГод + 1;
НоваяДата = ДобавитьМесяц(НоваяДата, 12);
КонецЦикла;
ПромДата = ДобавитьМесяц(НоваяДата, - 12); //ввел промежуточную дату после подсчета лет для
// корректного перехода февраля месяца, если он есть.
НоваяДата = ДобавитьМесяц(ПромДата, 1);
Пока НоваяДата <= ПеремДата + ДеньКоррекции Цикл
ВремМес = ВремМес + 1;
НоваяДата = ДобавитьМесяц(ПромДата, 1 + ВремМес);
КонецЦикла;
НоваяДата = ДобавитьМесяц(КонМесДатыС, 12*ВремГод + ВремМес);
ВремДней = РазницаДатыС + ?(Год(ПеремДата + ДеньКоррекции)=Год(НоваяДата), ДеньГода(ПеремДата + ДеньКоррекции) - ДеньГода(НоваяДата), ДеньГода(КонецГода(НоваяДата)) - ДеньГода(НоваяДата) + ДеньГода(ПеремДата + ДеньКоррекции));
Возврат "" + ВремГод + "/" + ВремМес + "/" + ВремДней;
Иначе
НовСообщ = Новый СообщениеПользователю;
НовСообщ.Текст = "Проверьте формат дат";
НовСообщ.Сообщить();
КонецЕсли;
КонецФункции
// Страничка автора: https://infostart.ru/profile/654641/
Функция РазностьДат2(ДатаНач, ДатаПо, ДатаДо)
Если ДатаПо <> Дата('00010101') Тогда
ПеремДата = ДатаПо;
ДеньКоррекции = 3600*24; //для корректировки даты ПО
ИначеЕсли ДатаДо <> Дата('00010101') Тогда
ПеремДата = ДатаДо;
ДеньКоррекции = 0;
Иначе
НовСообщ = Новый СообщениеПользователю;
НовСообщ.Текст = "Выберите одну дату";
НовСообщ.Сообщить();
КонецЕсли;
РазницаДатыС = День(КонецМесяца(ДатаНач)) - День(ДатаНач);
КонМесДатыС = КонецМесяца(ДатаНач);
Если ПеремДата >= ДатаНач Тогда
ВремГод = 0; ВремМес = 0; ВремДней = 0;
НоваяДата = ДобавитьМесяц(КонМесДатыС, 12);
Пока НоваяДата <= ПеремДата + ДеньКоррекции Цикл
ВремГод = ВремГод + 1;
НоваяДата = ДобавитьМесяц(НоваяДата, 12);
КонецЦикла;
ПромДата = ДобавитьМесяц(НоваяДата, - 12); //ввел промежуточную дату после подсчета лет для
// корректного перехода февраля месяца, если он есть.
НоваяДата = ДобавитьМесяц(ПромДата, 1);
Пока НоваяДата <= ПеремДата + ДеньКоррекции Цикл
ВремМес = ВремМес + 1;
НоваяДата = ДобавитьМесяц(ПромДата, 1 + ВремМес);
КонецЦикла;
НоваяДата = ДобавитьМесяц(КонМесДатыС, 12*ВремГод + ВремМес);
ВремДней = РазницаДатыС + ?(Год(ПеремДата + ДеньКоррекции)=Год(НоваяДата), ДеньГода(ПеремДата + ДеньКоррекции) - ДеньГода(НоваяДата), ДеньГода(КонецГода(НоваяДата)) - ДеньГода(НоваяДата) + ДеньГода(ПеремДата + ДеньКоррекции));
Возврат "" + ВремГод + "/" + ВремМес + "/" + ВремДней;
Иначе
НовСообщ = Новый СообщениеПользователю;
НовСообщ.Текст = "Проверьте формат дат";
НовСообщ.Сообщить();
КонецЕсли;
КонецФункции
2
комментарии
Администратор для Геннадия
22 янв 2024
Здравствуйте, Геннадий. Ответил Вам на e-mail. Продублирую и сюда:
1)В основном на сайте представлены мои «куски» кода 1С. Но иногда также перепечатываю понравившиеся примеры из сети которые размещены в свободном доступе. Извиняюсь, что не указал авторства – обычно указываю…
2)Вставил адреса ссылки в комментарии на:
// оригинал статьи: https://infostart.ru/1c/articles/2004076/
// страничка автора: https://infostart.ru/profile/654641/
Кликабельными, к сожалению сделать не могу по тех.причинам.
3)Код поправил
4)Если есть претензии – пришлите ответным письмом – удалю Ваш код.
// С уважением, Администратор сайта koder.by
1)В основном на сайте представлены мои «куски» кода 1С. Но иногда также перепечатываю понравившиеся примеры из сети которые размещены в свободном доступе. Извиняюсь, что не указал авторства – обычно указываю…
2)Вставил адреса ссылки в комментарии на:
// оригинал статьи: https://infostart.ru/1c/articles/2004076/
// страничка автора: https://infostart.ru/profile/654641/
Кликабельными, к сожалению сделать не могу по тех.причинам.
3)Код поправил
4)Если есть претензии – пришлите ответным письмом – удалю Ваш код.
// С уважением, Администратор сайта koder.by
Геннадий
20 янв 2024
Доброго времени суток. У Вас на сайте написано про защиту интеллектуальной собственности, а тем не менее Вы перепечатываете мою публикацию без указания ссылки! Я, в принципе, не сильно против, но мне было бы приятно! Второй момент: Вы вырвали из контекста комментарии и читая их здесь - это "бред". Третий момент: в коде есть ошибка!
____________________
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник