Начнем с самого простого. Всегда необходимо помнить, что при применении математических действий к датам, результат всегда будет в секундах. Если необходимо получить текущее время(в секундах) , необходимо от текущей даты отнять дату начала дня:
ТекущееВремя = ТекущаяДата() - НачалоДня(ТекущаяДата());
//36 728 = 28.08.2024 10:09:21 - 28.08.2024 0:00:00
Вставка 1.
1. Сравнение даты и времени.
Бывает необходимо сравнить дату имеющую тип дата только время, с текущим временем. Например, при разработке систем контроля и учета рабочего времени, когда в конфигурации указывается время начала и конца рабочей смены (ВремяНачала - 08:00, ВремяКонца - 18:00). Если просто сравнивать с текущей датой, текущая дата будет всегда больше, потому что тип дата только время, возвращает дату в виде - 01.01.0001 8:00:00. Для решения данной проблемы, можно получить значение обоих дат в секундах, отняв от их значения нулевую дату.
НулеваяДата = Дата(01,01,0001,0,0,0);
//Значение нулевой даты будет 01.01.0001 0:00:00
ТекущееВремя = ТекущаяДата() - НачалоДня(ТекущаяДата());
//36 728 = 28.08.2024 10:09:21 - 28.08.2024 0:00:00
ВремяНачала = Дата(01,01,0001,8,00,00);
//Тип Дата только время
НачалоРабочегоДня = ВремяНачала - НулеваяДата;
//28 800 = 01.01.0001 8:00:00 - 01.01.0001 0:00:00
Вставка 2.
После этого сравнить количество секунд из обоих примеров и выполнить какие либо действия. Например:
Если ТекущееВремя > НачалоРабочегоДня Тогда
//Как пример обозначает, что сотрудник опоздал. Соответственно
//пишем программный код, обрабатывающий данное событие
КонецЕсли;
Вставка 3.
Так же, можно поступить по другому. Можно текущую дату привести к виду тип дата только время, и после этого производить сравнение:
НулеваяДата = Дата(01,01,0001,0,0,0);
ВремяНачала = Дата(01,01,0001,8,00,00);
ТекущееВремя = НулеваяДата + (ТекущаяДата() - НачалоДня(ТекущаяДата()));
//01.01.0001 8:39:09 = 01.01.0001 0:00:00 + 31 575
//Сравниваем даты (тип дата только время)
Если ТекущееВремя > ВремяНачала Тогда
//Сотрудник опоздал
КонецЕсли;
Вставка 4.
Теперь попробуем узнать на какое время, все таки, опоздал сотрудник:
Опоздание = ВремяСейчас - НачалоРабочегоДня;
//10 965 = 39 765 - 28 800
ОпозданиеВремя = НулеваяДата + Опоздание;
//01.01.0001 3:02:45 = 01.01.0001 0:00:00 + 10 965
//Тип Дата только время
Вставка 5.
2. Разность дат.
Вот так, получим разность дат:
НулеваяДата = Дата(01,01,0001,0,0,0);
РазностьДат = ПроизвольнаяДатаВремя1 - ПроизвольнаяДатаВремя2;
//147 170 = 02.09.2024 17:26:55 - 01.09.2024 0:34:05
РазностьДатДата = НулеваяДата + РазностьДат;
//02.01.0001 16:52:50 = 01.01.0001 0:00:00 + 147 170
Вставка 6.
Нужно обратить внимание, что в результате добавился день. Может добавиться и месяц и год. Все зависит от того, на какой величины временной отрезок даты отстоят друг от друга. Так же необходимо помнить, что в нулевой дате уже присутствует один день, один месяц, и один год. Соответственно результат получится вида - 02.01.0001 16:52:50. Мы можем используя стандартные функции платформы извлечь из даты необходимые нам данные, ну и дальше преобразовать их, как нам угодно. Вот эти функции:
ДатаГод = Год(Дата);
ДатаМесяц = Месяц(Дата);
ДатаДень = День(Дата);
ДатаЧас = Час(Дата);
ДатаМинута = Минута(Дата);
ДатаСекунда = Секунда(Дата);
Вставка 7.
Вот так можно получить данные:
//Извлекаем из даты количество месяцев, дней, чесов, минут, секунд. Так как в нулевой дате уже
//имеется один день, один месяц, один год, от полученных значений месяца и дня отнимаем 1
МесяцРазностьДатДата = Месяц(РазностьДатДата) - 1;
ДеньРазностьДатДата = День(РазностьДатДата) - 1;
ЧасРазностьДатДата = Час(РазностьДатДата);
МинутаРазностьДатДата = Минута(РазностьДатДата);
СекундаРазностьДатДата = Секунда(РазностьДатДата);
//В зависимости от полученных значений формируем сообщение пользователю
ТекстСообщения = "Разность дат составляет: ";
//Если количество месяцев больше ноля, выводим месяцы в сообщении
Если МесяцРазностьДатДата > 0 Тогда
ТекстСообщения = ТекстСообщения + "Месяцев - " + МесяцРазностьДатДата + " : ";
КонецЕсли;
//Если количество дней больше ноля, выводим дни в сообщении
Если ДеньРазностьДатДата > 0 Тогда
ТекстСообщения = ТекстСообщения + "Дней - " + ДеньРазностьДатДата + " : ";
КонецЕсли;
//Добавляем к сообщению значения времени
ТекстСообщения = ТекстСообщения + "Часов - " + ЧасРазностьДатДата + " : Минут - " + МинутаРазностьДатДата + " : Секунд - " + СекундаРазностьДатДата;
//Выводим сообщение пользователю
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ТекстСообщения ;
Сообщение.Сообщить();
//Разность дат составляет Дней - 1 : Часов - 16 : Минут - 52 : Секунд - 50
Вставка 8.
Деля и умножая значение даты в секундах, это в наших примерах РазностьДат, на 12, 24 или 60, можем получить количество лет, месяцев, дней, часов, минут, секунд:
//Дата в секундах
РазностьДат = 147 170;
//Количество часов
КоличествоЧасов = 147 170 / 60 / 60;
//Количество полных часов (40)
КоличествоПолныхЧасов = Цел(КоличествоЧасов);
//Количество минут из остатка (52)
КоличествоПолныхМинут = 60 * (КоличествоЧасов - КоличествоПолныхЧасов);
Вставка 9.
Ну и последнее в этом разделе, пример как от даты отнять время:
НулеваяДата = Дата(01,01,0001,0,0,0);
//От даты отнимаем время
РазностьДатаВремя = НулеваяДата + (ПроизвольнаяДатаВремя - ТолькоВремя);
Вставка 10.
3. Сложение дат.
Говорить о сложении или вычитании дат, наверно следует в контексте того, что имеет смысл прибавлять к дате, либо вычитать из нее, только количество лет, месяцев, дней, часов, минут, секунд. Сложение двух конкретных каких то дат не имеет смысла.
Дата1Секунды = ПроизвольнаяДатаВремя1 - НулеваяДата;
//63 860 960 800 = 03.09.2024 11:46:40 - 01.01.0001 0:00:00
Дата2Секунды = ПроизвольнаяДатаВремя2 - НулеваяДата;
//63 860 745 600 = 01.09.2024 0:00:00 - 01.01.0001 0:00:00
СуммаДат = НулеваяДата + Дата1Секунды + Дата2Секунды;
//04.05.4048 11:46:40 =01.01.0001. 0:00:00 + 63 860 960 800 + 63 860 745 600
Вставка 11.
Необходимость сложения может возникнуть при расчете общего количества отработанного времени на предприятии, если сотрудник несколько раз увольнялся и повторно устраивался на работу. Допустим сотрудник работал с 01.01.2024 по 05.03.2024 затем уволился, но снова устроился на работу 20.07.2024 и работает по сей день. Например необходимо посчитать общее время которое он отработал:
НулеваяДата = Дата(01,01,0001,0,0,0);
//Первый период в секундах
ПервыйПериод = Период1Конец - Период1Начало;
//Второй период в секундах
ВторойПериод = ТекущаяДата() - Период2Начало;
//Общее количество отработанного времени тип Дата
ВсегоОтработано = НулеваяДата + ПервыйПериод + ВторойПериод;
//Или общее количество отработанного времени в секундах
ВсегоОтработано = ПервыйПериод + ВторойПериод;
Вставка 12.
Дальше, если необходимо получить количество в виде лет, месяцев, дней, часов, минут, секунд используем вариант на вставке 8. если же нас интересует количество отработанных дней, часов, минут можно использовать вариант на вставке 9.
Иногда, в частности при разработке систем контроля и учета времени, может понадобиться суммировать время. Смотри вставки 2 - 5. Как пример приведу функцию:
//ВидВозврата строка "Дата" либо "Секунда"
Функция СуммаВремя(ДатаККоторойПрибавить,ДатаСколькоПрибавить,ВидВозврата)
Если ТипЗнч(ДатаККоторойПрибавить) <> Тип("Дата") ИЛИ ТипЗнч(ДатаСколькоПрибавить) <> Тип("Дата") Тогда
//Если в параметрах передана не дата возвращаем пустую дату
Возврат Дата(01,01,0001,0,0,0);
КонецЕсли;
Если ВидВозврата = "Дата" Тогда
//Суммируем время
РезультатСложения = ДатаККоторойПрибавить + (ДатаСколькоПрибавить - НулеваяДата);
//Возвращаем сумму дат в виде даты
Возврат РезультатСложения;
ИначеЕсли ВидВозврата = "Секунда" Тогда
//Получаем значение дат в секундах
НулеваяДата = Дата(01,01,0001,0,0,0);
Дата1 = ДатаККоторойПрибавить - НулеваяДата;
Дата2 = ДатаСколькоПрибавить - НулеваяДата;
РезультатСложения = Дата1 + Дата2;
//Возвращаем сумму дат в виде количества секунд
Возврат РезультатСложения;
Иначе
//Если третий параметр задан неправильно возвращаем пустую дату
Возврат Дата(01,01,0001,0,0,0);
КонецЕсли;
КонецФункции
Вставка 13.
Переменная СуммаВремя может быть какой то глобальной переменной, либо записью в регистре сведений и т. п.
При разработке сложных решений обратите внимание на то, что при добавлении к дате доли секунды(спасибо за дополнение SerVer1C), даты будут выглядеть идентично но будут различаться по факту:
дата1 = ТекущаяДата();
дата2 = дат1 + 0.1;
РавныЛи = дата1 = дата2;
//Ложь = 29.08.2024 9:04:00 = 29.08.2024 9:04:00
//Система визуально показывает, что даты одинаковые но они не равны!
Вставка 14.
Проверено на следующих конфигурациях и релизах:
- Розница, редакция 3.0, релизы 3.0.3.169