Работа с датами в "1С:Предприятие"

28.08.24

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

Как оказалось, очевидное не всегда очевидно. Особенно для тех, кто только начинает создавать конфигурации на платформе "1С:Предприятие". Статья коснется вопросов работы с датами при написании программного кода.

Бесплатные

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

Узнавайте о новых бесплатных решениях в нашей телеграм-группе Инфостарт БЕСПЛАТНО

Наименование Скачано Бесплатно
Работа с датами в "1С:Предприятие":
.epf 9,63Kb
25 Скачать бесплатно

Начнем с самого простого. Всегда необходимо помнить, что при применении математических действий к датам, результат всегда будет в секундах. Если необходимо получить текущее время(в секундах) , необходимо от текущей даты отнять дату начала дня:

ТекущееВремя = ТекущаяДата() - НачалоДня(ТекущаяДата());
//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

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

Дата работа с датами сумма дат разность дат.

См. также

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

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

14.05.2025    5466    DeerCven    15    

57

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

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

21.05.2024    46506    dimanich70    83    

165

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

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

1 стартмани

18.03.2024    6873    6    John_d    13    

59

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

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

12.02.2024    57636    atdonya    31    

68

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

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

30.11.2023    8650    ke.92@mail.ru    17    

68

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

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    22842    YA_418728146    8    

174
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. kuzyara 2210 28.08.24 11:06 Сейчас в теме
[FAQ 1С] » Работа с Датами (Временем)  
https://helpf.pro/faq/cat/36.html
eufes; alexsy; +2 Ответить
5. lv0v4ik 14 28.08.24 14:47 Сейчас в теме
(2) Спасибо за ссылку. Добавил себе в закладки. Хотя статья больше про выделение из даты времени и работы с ним.
3. SerVer1C 993 28.08.24 13:03 Сейчас в теме
Про самое интересное не написали: что можно к дате прибавить дробное значение секунд.
Визуально даты будут одинаковыми, но не равными программно. Вот где могут всплыть нежданчики.
дат1 = ТекущаяДата();
дат2 = дат1 + 0.1;
РавныЛи = дат1 = дат2;
Сообщить(дат1);
Сообщить(дат2);
Сообщить(РавныЛи);
Lem0n; maxis33; +2 Ответить
4. lv0v4ik 14 28.08.24 14:44 Сейчас в теме
(3) Согласен. Только,если программист будет реализовать учетные задачи критичные к долям секунды, наверно он будет способен просчитать описанную вами ситуацию. Но все равно спасибо за Ваше уточнение, если Вы не против я его добавлю в статью. Статья писалась больше для тех кто впервые столкнулся с подобными задачами.
6. nuctoh 31 30.08.24 04:57 Сейчас в теме
Что за дичь я только что прочитал? Если надо временной интервал между датами, то я просто вычту из большей меньшую и прибавлю разность к нулевой дате. Одна строка кода:
Интервал = '00010101' + (ДатаБ - ДатаМ);
вместо монструозной процедуры.

С суммой еще бредовей. Если надо получить временной интервал, равный сумме времен суток (оставим вопрос - зачем вообще это может понадобиться), то делается это также одной строкой:
Интервал = '00010101' + (Дата1-НачалоДня(Дата1)) + (Дата2-НачалоДня(Дата2));
А в функции автора еще и косяк есть - если суммарных часов будет более 23, то 1С выдаст ошибку преобразования.

Вообще, этот опус выдает в авторе полнейшего нубаса в программировании - во-первых желание придумать свой непонятный способ решить простую задачу сложно, а во-вторых вместо "НЕ Вар1=Вар2" надо писать "Вар1<>Вар2" потому что "<>" это одна операция, а "НЕ =" - две, сравнения и отрицания.
7. lv0v4ik 14 04.09.24 13:07 Сейчас в теме
(6) Спасибо за Ваши советы. Я действительно не считаю себя гуру в программировании. Плохо, что в свое время, мне не попался кто то вроде Вас. Я перерыл море сайтов в интернете, везде описание только стандартных моментов работы с датами, типа период или прибавить день, час и т. п. Как я и написал в самом начале, не всегда очевидное - очевидно. Поэтому и написал статью для начинающих, надеясь дополнить ее, как раз опытом таких как Вы подключившихся к обсуждению.
8. nuctoh 31 28.09.24 06:31 Сейчас в теме
(7) достаточно почитать правила преобразования типов в 1С в базовом курсе и чуть чуть подумать. Да, и использовать главный принцип 1С, которого надо придерживаться примерно всегда при разработке - решай задачу максимально простым и тривиальным способом, иногда даже в ущерб производительности - чтобы человек, который будет дорабатывать твой код, понял что код делает и не сломал его.
9. GlukAl 12.11.25 17:10 Сейчас в теме
НулеваяДата = Дата(01,01,0001,0,0,0);


Вариант синтаксиса: По составляющим
Дата(<Год>, <Месяц>, <День>, <Час>, <Минута>, <Секунда>)

чтобы не запутывать других писали бы проще
НулеваяДата = Дата(1,1,1);
Для отправки сообщения требуется регистрация/авторизация