Время в 1с
В программе 1с 8-ой версии Дата это объект, который состоит из самой календарной даты и времени.
При программировании можно использовать следующие конструкции для оперирования временем:
Дата
Чтобы получить объект «Дата» существует несколько способов. Например, чтобы установить программно дату «30.12.2010 23:59:59»:
Док.Дата = '20101230235959' ;
Док.Дата = Дата("20101230235959");
Док.Дата = Дата(2010,12,30,23,59,59);
Док.Дата = Дата("2010-12-30 23:59:59");
В запросах для получения даты используется метод «ДатаВремя»:
ДатаВремя(2010,12,30,23,59,59)
Пустая дата это нулевая секунда нулевого года, а т.к. отсчет идет от Рождества Христова, то и получается следующая запись:
ПустаяДата = Дата(0001,01,01,00,00,00);
//Причем секунды записывать не обязательно.
ПустаяДата = Дата(0001,01,01);
В запросе это будет выглядеть проще:
ДатаВремя(1,1,1)
Чтобы вычислить разницу дат нужно из большей даты вычесть меньшую, но при этом программа вернет разницу в секундах.
Разность дат:
РазностьВСекундах = Дата("20101230235959") - Дата("20081115035529");//67 032 270
Поэтому надо исходить из того какой тип результата нас интересует. Например, если нас интересует только разница в днях, то можно написать так:
РазностьВСекундах = Дата("20101230235959") - Дата("20081115035529");
РазностьВДнях = РазностьВСекундах/86400;
В случае если нужна полная разница(Лет, месяцев, дней) между датами то есть следующие варианты:
1. Алгоритм который первый приходит в голову, НЕ точный:
РазностьВСекундах = Дата("20101230235959") - Дата("20081115035529");
РазностьВДнях = РазностьВСекундах/86400;
ПолнаяРазница = «Лет: » + Цел(РазностьВДнях/365) + « Месяцев: » + Цел((РазностьВДнях%365)/30) + « Дней: » + (РазностьВДнях%365)%30;
Ещё раз подчеркну, что предыдущий алгоритм приблизительный т.к. не учитывает точное количество дней в месяце.
2. Более точен следующий алгоритм описанный в типовой конфигурации, например, в ЗУП:
Процедура РазобратьРазностьДат(Дата1, Дата2, Лет = 0, Месяцев = 0, Дней = 0) Экспорт
Лет = 0;
Месяцев = 0;
Дней = 0;
Если Дата1 > Дата2 Тогда
ВременнаяДата = Дата1;
Если День(ВременнаяДата) < День(Дата2) Тогда
Дней = (ВременнаяДата - ДобавитьМесяц(ВременнаяДата,-1))/86400;
ВременнаяДата = ДобавитьМесяц(ВременнаяДата,-1);
КонецЕсли;
Если Месяц(ВременнаяДата) < Месяц(Дата2) Тогда
ВременнаяДата = ДобавитьМесяц(ВременнаяДата,-12);
Месяцев = 12;
КонецЕсли;
Лет = Макс( Год(ВременнаяДата) - Год(Дата2), 0);
Месяцев = Макс(Месяцев + Месяц(ВременнаяДата) - Месяц(Дата2), 0);
Дней = Макс(Дней + День(ВременнаяДата) - День(Дата2), 0);
// скорректируем отображаемое значение, если "вмешалось" разное количество дней в месяцах
Если Дата2 <> (ДобавитьМесяц(Дата1,-Лет*12-Месяцев)-Дней*86400) Тогда
Дней = Дней + (День(КонецМесяца(Дата2)) - День(НачалоМесяца(Дата2))) - (День(КонецМесяца(ДобавитьМесяц(Дата1,-1))) - День(НачалоМесяца(ДобавитьМесяц(Дата1,-1))));
КонецЕсли;
КонецЕсли;
КонецПроцедуры // РазобратьРазностьДат
Для запросов же можно использовать способ предложенный здесь: http://kb.mista.ru/article.php?id=664
Автор взял за основу предыдущую процедуру и перевел её на язык запросов так для вычисления года нужно записать следующее(я немного изменил запрос для наглядности):
|ВЫБОР
| КОГДА ГОД(ВЫБОР
| КОГДА МЕСЯЦ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ) < МЕСЯЦ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ, МЕСЯЦ, -12)
| ИНАЧЕ ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ
| КОНЕЦ) - ГОД(&ДатаНачала) > 0
| ТОГДА ГОД(ВЫБОР
| КОГДА МЕСЯЦ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ) < МЕСЯЦ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ, МЕСЯЦ, -12)
| ИНАЧЕ ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ
| КОНЕЦ) - ГОД(&ДатаНачала)
| ИНАЧЕ 0
|КОНЕЦ
Для месяца:
|ВЫБОР
| КОГДА ВЫБОР
| КОГДА МЕСЯЦ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ) < МЕСЯЦ(&ДатаНачала)
| ТОГДА 12
| ИНАЧЕ 0
| КОНЕЦ + МЕСЯЦ(ВЫБОР
| КОГДА МЕСЯЦ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ) < МЕСЯЦ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ, МЕСЯЦ, -12)
| ИНАЧЕ ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ
| КОНЕЦ) - МЕСЯЦ(&ДатаНачала) > 0
| ТОГДА ВЫБОР
| КОГДА МЕСЯЦ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ) < МЕСЯЦ(&ДатаНачала)
| ТОГДА 12
| ИНАЧЕ 0
| КОНЕЦ + МЕСЯЦ(ВЫБОР
| КОГДА МЕСЯЦ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ) < МЕСЯЦ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ, МЕСЯЦ, -12)
| ИНАЧЕ ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ
| КОНЕЦ) - МЕСЯЦ(&ДатаНачала)
| ИНАЧЕ 0
|КОНЕЦ
Для дня:
|ВЫБОР
| КОГДА ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1), &ДатаОкончания, ДЕНЬ)
| ИНАЧЕ 0
| КОНЕЦ + ДЕНЬ(ВЫБОР
| КОГДА МЕСЯЦ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ) < МЕСЯЦ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ, МЕСЯЦ, -12)
| ИНАЧЕ ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ
| КОНЕЦ) - ДЕНЬ(&ДатаНачала) > 0
| ТОГДА ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1), &ДатаОкончания, ДЕНЬ)
| ИНАЧЕ 0
| КОНЕЦ + ДЕНЬ(ВЫБОР
| КОГДА МЕСЯЦ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ) < МЕСЯЦ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ, МЕСЯЦ, -12)
| ИНАЧЕ ВЫБОР
| КОГДА ДЕНЬ(&ДатаОкончания) < ДЕНЬ(&ДатаНачала)
| ТОГДА ДОБАВИТЬКДАТЕ(&ДатаОкончания, МЕСЯЦ, -1)
| ИНАЧЕ &ДатаОкончания
| КОНЕЦ
| КОНЕЦ) - ДЕНЬ(&ДатаНачала)
| ИНАЧЕ 0
|КОНЕЦ
Время
Для получения значений времени используются следующие методы:
СекундаДаты = Секунда(Дата("20081115035529")); // 29
МинутаДаты = Минута(Дата("20081115035529")); // 55
ЧасДаты = Час(Дата("20081115035529")); // 3
В запросах для получения времени используются функции с такими же названиями:
Секунда(ДатаВремя(2008,11,15,03,55,29))
Минута(ДатаВремя(2008,11,15,03,55,29))
Час(ДатаВремя(2008,11,15,03,55,29))