gifts2017

Функция для вычисления разницы между двумя датами

Опубликовал Валерий Сухих (vsuh) в раздел Программирование - Универсальные функции

Функция РазностьДат

Простая функция для вычисления разности между датами в любых единицах.

От типовой отличается тем, что реализована функцией языка запросов РАЗНОСТЬДАТ.

В приложении - обработка, демонстрирующая работу функции.

Скачать файлы

Наименование Файл Версия Размер
РазностьДат.epf 31
.epf 7,94Kb
20.03.13
31
.epf 7,94Kb Скачать

См. также

Вознаграждение за ответ
Сумма: 0 $m
Добавили:
Алексей Алёхин (alexin08) (10.00 $m)
Подписаться Добавить вознаграждение

Комментарии

1. Вова Вишин (Tahallus) 20.03.13 17:16
Я вижу Вы открыли для себя РАЗНОСТЬДАТ
2. anry mc (AnryMc) 20.03.13 17:32
Долго думал. Ставить или нет "-". У человека всего 3 звездочки (уже 2). И решил, что будет - 1.
3. straus (straus) 20.03.13 18:28
4. Юрий Осипов (yuraos) 20.03.13 18:32
Как много нам (1) открытий чудных,
готовит мануала дух!
И опыт - сын багов (ударение на первый слог) трудных,
И гений - алгоритмов друг!

---
ааасторожно надо мануал 1с-ный публиковать.

сначала надо группой поддержки заручиться...
...которая восторженно ох-ахает и
плусует-плусует-плусует!!!
:)
5. Юрий Осипов (yuraos) 20.03.13 18:42
(1) Tahallus,
похоже разработчики платформы,
которые лепили встроенные функции и те
которые реализовывали функционал запросов
друг о друге ничего не знали.
---
иначе бы, наверное, была встроенная функция РАЗНОСТЬДАТ()
и не было бы повода для такой статьи
:)
6. Юрий Осипов (yuraos) 20.03.13 18:48
Tahallus,
к стати поздравляю!
Инфостарт рассылает спам что ты автор этой публикации
:)
Смотри скриншот.
Прикрепленные файлы:
7. anry mc (AnryMc) 20.03.13 18:51
(6) yuraos, Точно. И мне тоже ;-)))
8. andrewks 20.03.13 18:56
(6) yuraos, в письмах, которые приходят мне, с некоторых пор не только автор, но и название не отображается.

Тема: "Инфостарт - Новый комментарий"
и так - для любой ветки
9. Юрий Осипов (yuraos) 20.03.13 19:10
(8) andrewks,

Любопытно скрипты работают на Инфорстарте...
А ты через какой браузер ходишь по Инфостарту ???

Я через Оперу и его почтовый клиент юзаю.
10. andrewks 20.03.13 19:17
(9) yuraos, у меня The Bat!. но это, собственно, не важно, ибо в исходнике письма Subject приходит именно такой, проверял.
раньше было нормально, слетело после падения/переезда на новый сервер
11. Юрий Осипов (yuraos) 20.03.13 19:39
(10) andrewks,
в самом деле от браузера (и тем более от клиента)
вроде не должна рассылка зависеть...


слетело после падения/переезда на новый сервер


имеешь ввиду, когда Инфостарт начал глючить не по децки,
а потом совсем накрылся медным тазом
и после чего они развернули бэкап (уж не знаю на каком серваке - новом или старом) ???
12. Ярослав Радкевич (WKBAPKA) 20.03.13 21:10
ну для кого то это и открытие... хотя 1С могла бы сделать функцию, как бэ не сложно
13. Ярослав Радкевич (WKBAPKA) 20.03.13 21:14
куку .. РАЗНОСТЬДАТ реализовано в запросах, а чел выложил расчет разницы в датах не в запросе (обработку не качал, так что предполагаю)... в языке 8-ки это, как в 7.7. не реализовано, так что зря вы нападаете на начинающего программиста... т.к. я вредный, поставлю плюс, поддержу молодежь!
14. anry mc (AnryMc) 20.03.13 21:30
(6) yuraos, Самое интересное, что из одних веток письма приходят правильно...
15. anry mc (AnryMc) 20.03.13 21:32
(13) WKBAPKA,
Да ещё в разных единицах измерения.
Ты меня почти убедил. Нетрализую свой "-".
16. smaharbA (smaharbA) 20.03.13 21:34
(13) не поверите - в 77 реализовано в одно действие
17. anry mc (AnryMc) 20.03.13 21:53
18. andrewks 20.03.13 22:18
(13) WKBAPKA, реализуется в одну строку: (Макс(Дата1,Дата2)-Мин(Дата1,Дата2))/СекундВЕдинице

я понимаю, что РАЗНОСТЬДАТ в запросе - это круто и гламурно, но дёргать из-за этих мелочей сервер явно чрезмерно. а если уж эта функция окажется в цикле с кол-вом итераций, например, 10000, так и вообще вредно
19. andrewks 20.03.13 22:19
(16) как насчёт секунд/минут/часов?
20. andrewks 20.03.13 22:19
я не вредный, плюс ставить не буду, минус тоже
21. Юрий Осипов (yuraos) 20.03.13 22:20
(13) WKBAPKA,
вот вам моя реализация в составе подсистемы ViewValues
и совершенно бесплатно:



// возвращает дату смещенную на указанное число интервалов указанного типа
Функция ДобавитьКДате(Знач ИсхДата, ТипИнтервала, Знач ЧислоИнтервалов) Экспорт
	Если ТипЗнч(ИсхДата) <> Тип("Дата") Тогда
		ИсхДата = '0001-01-01';
	КонецЕсли; 
	Если ТипЗнч(ЧислоИнтервалов) <> Тип("Число") Тогда
		ЧислоИнтервалов = 0;
	КонецЕсли;
	
	ТекстЗапроса = "ВЫБРАТЬ
	|	ДОБАВИТЬКДАТЕ(&ИсхДата, !ТипИнтервала!, &ЧислоИнтервалов) КАК СмещДата"; // !ТипИнтервала! 
	
	Если Нрег(ТипИнтервала) = НРег("СЕКУНДА") ИЛИ Нрег(ТипИнтервала) = НРег("СЕК") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "СЕКУНДА");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("МИНУТА") ИЛИ Нрег(ТипИнтервала) = НРег("МИН") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "МИНУТА");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("ЧАС") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "ЧАС");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("ДЕНЬ") ИЛИ Нрег(ТипИнтервала) = НРег("ДНИ") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "ДЕНЬ");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("НЕДЕЛЯ") ИЛИ Нрег(ТипИнтервала) = НРег("НЕД") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "НЕДЕЛЯ");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("ДЕКАДА") ИЛИ Нрег(ТипИнтервала) = НРег("ДЕК") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "ДЕКАДА");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("МЕСЯЦ") ИЛИ Нрег(ТипИнтервала) = НРег("МЕС") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "МЕСЯЦ");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("КВАРТАЛ") ИЛИ Нрег(ТипИнтервала) = НРег("КВ") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "КВАРТАЛ");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("ПОЛУГОДИЕ") ИЛИ Нрег(ТипИнтервала) = НРег("ПОЛГОДА") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "ПОЛУГОДИЕ");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("ГОД") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "ГОД");
	Иначе
		ВызватьИсключение(
		"Непредусмотренный тип интервала '"+ТипИнтервала+"' для добавления к дате !");
		Возврат Null;
	КонецЕсли; 
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("ИсхДата", ИсхДата);
	Запрос.УстановитьПараметр("ЧислоИнтервалов", ЧислоИнтервалов);
	
	тзРезультат = Запрос.Выполнить().Выгрузить();
	
	Возврат тзРезультат[0][0];
КонецФункции

// возвращает разницу между переданными датами в интервалах указанного типа
Функция РазностьДат(Знач ИсхДатаНач, Знач ИсхДатаКон, ТипИнтервала) Экспорт	
	Если ТипЗнч(ИсхДатаНач) <> Тип("Дата") Тогда
		ИсхДатаНач = '0001-01-01';
	КонецЕсли; 
	Если ТипЗнч(ИсхДатаКон) <> Тип("Дата") Тогда
		ИсхДатаКон = '0001-01-01';
	КонецЕсли; 
	
	ТекстЗапроса = "ВЫБРАТЬ
	|	РАЗНОСТЬДАТ(&ИсхДатаНач, &ИсхДатаКон, !ТипИнтервала!) КАК ЧислоИнтервалов"; // !ТипИнтервала! 
	
	Если Нрег(ТипИнтервала) = НРег("СЕКУНДА") ИЛИ Нрег(ТипИнтервала) = НРег("СЕК") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "СЕКУНДА");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("МИНУТА") ИЛИ Нрег(ТипИнтервала) = НРег("МИН") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "МИНУТА");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("ЧАС") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "ЧАС");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("ДЕНЬ") ИЛИ Нрег(ТипИнтервала) = НРег("ДНИ") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "ДЕНЬ");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("МЕСЯЦ") ИЛИ Нрег(ТипИнтервала) = НРег("МЕС") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "МЕСЯЦ");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("КВАРТАЛ") ИЛИ Нрег(ТипИнтервала) = НРег("КВ") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "КВАРТАЛ");
	ИначеЕсли Нрег(ТипИнтервала) = НРег("ГОД") Тогда
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "!ТипИнтервала!", "ГОД");
	Иначе
		ВызватьИсключение(
		"Непредусмотренный тип интервала '"+ТипИнтервала+"' для вычисления разницы дат !");
		Возврат Null;
	КонецЕсли; 
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("ИсхДатаНач", ИсхДатаНач);
	Запрос.УстановитьПараметр("ИсхДатаКон", ИсхДатаКон);
	
	тзРезультат = Запрос.Выполнить().Выгрузить();
	
	Возврат тзРезультат[0][0];
КонецФункции



...Показать Скрыть


;)
22. Юрий Осипов (yuraos) 20.03.13 22:25
(21)(18) andrewks,
Хотя говорят в платформе 8.2.17 добавили функцию,
позволяющую время в миллисекундах отмерять...
мож они и эти функции наконец добавили ???
а то стремно и позорно как-то...сервер напрягать для посчета смещенной даты.
23. Ярослав Радкевич (WKBAPKA) 20.03.13 22:29
какой кошмар? а мне то зачем?
24. andrewks 20.03.13 22:38
(23) WKBAPKA, берите, пока дают ))
25. Юрий Осипов (yuraos) 20.03.13 22:39
(23) WKBAPKA,
да так ... за компанию.
извини если что.
26. andrewks 20.03.13 22:41
(22) yuraos, а смысл добавлять? лично я не вижу. если хронометр с миллисекундами может быть очень полезен, то тут всё реализуется примитивными арифметическими операциями
27. smaharbA (smaharbA) 21.03.13 00:30
(26) ну положим в толстом миллисекунды реализуются штатно
28. andrewks 21.03.13 08:09
29. smaharbA (smaharbA) 21.03.13 10:43
(27) для толстого
Перем Скрыпт;
Процедура ДокументСформирован(Поле)
	Скрыпт=Поле.Документ.Script;
КонецПроцедуры

Процедура КнопкаВыполнитьНажатие(Кнопка)
	Пока Истина Цикл
		Попытка
			Скрыпт.ДатаМиллисекондов();
			Прервать;
		Исключение
		КонецПопытки;
	КонецЦикла;
	Сообщить(Скрыпт.ДатаМиллисекондов(0));
	Предупреждение(1,10);
	Сообщить(Скрыпт.ДатаМиллисекондов(0));
КонецПроцедуры

Процедура ПриОткрытии()
	ПолеHTMLДокумента=ЭлементыФормы.Найти("ПолеHTMLДокумента");
	Если ПолеHTMLДокумента=Неопределено Тогда
		ПолеHTMLДокумента=ЭлементыФормы.Добавить(Тип("ПолеHTMLДокумента"),"ПолеHTMLДокумента");
	КонецЕсли;
	ПолеHTMLДокумента.УстановитьТекст("<script type='text/javascript'>ДатаМиллисекондов=function(){return (new Date().getTime())}</script>");
	ПолеHTMLДокумента.УстановитьДействие("ДокументСформирован",Новый Действие("ДокументСформирован"));
КонецПроцедуры
...Показать Скрыть
30. anry mc (AnryMc) 21.03.13 11:07
(29) smaharbA,

Вызвало некоторый ступор
Перем Скрыпт
- это от какого корня?
31. andrewks 21.03.13 11:44
(29) smaharbA, что-то мне кажется, что при вызове браузера со скриптом миллисекунды уже не будут интересны ))
32. andrewks 21.03.13 11:45
(29) smaharbA, интересно а в 8.3 под линукс будет это работать? надо будет опробовать
33. anry mc (AnryMc) 21.03.13 11:50
(29) smaharbA,

ну положим в толстом миллисекунды реализуются штатно
- это что? Штатно?
34. andrewks 21.03.13 12:21
(33) AnryMc, формально - штатно. а то, что там прячется вражий браузер - это за кадром :)
35. Алекс Ю (AlexO) 21.03.13 12:32
(29) smaharbA,
и где тут штатная реализация средствами 1С?
(22) yuraos,
да, это ТекущаяУниверсальнаяДатаВМиллисекундах
36. Алекс Ю (AlexO) 21.03.13 12:33
(0) автор, форма сделана красиво, но какой смысл заложен запросом складывать\вычитать даты?
Показать пример использования РАЗНОСТЬДАТ?
37. Алекс Ю (AlexO) 21.03.13 12:55
(1)(24) andrewks,
точно, а то потом знания будут утеряны :)
38. Алекс Ю (AlexO) 21.03.13 13:04
Нет, ну согласитесь - форма-то красива, как в 7.7 практически :)
39. Юрий Осипов (yuraos) 21.03.13 16:24
(29) smaharbA,
а во эта и для ТОЛСТОГО и для НЕ-ТОЛСТОГО...
лишь бы Винда была, да ОДМИНЫ с правами чей-нибудь не нарулили
;)
// Функция, возвращающая время в миллисекундах или секундах.
//
&НаКлиентеНаСервереБезКонтекста
Функция ВремяВМиллисекундах()
    Попытка
        Script = Новый COMОбъект("MSScriptControl.ScriptControl");
        Script.Language = "javascript";
        Script.Timeout   = -1;
        Время = Script.Eval("var d = new Date(); d.getTime()");
    Исключение
        Время = ТекущаяДата();
    КонецПопытки;
    
    Возврат Время;
КонецФункции

// Пример.
//
Процедура ПримерИспользования()

   Начало = ВремяВМиллисекундах();
   КоличествоСтрок = 0;
   Для Каждого Элемент ИЗ Массив Цикл
         КоличествоСтрок = КоличествоСтрок  + 1;
         ...
   КонецЦикла;
   Конец  = ВремяВМиллисекундах();

   ВремяВыполнения = (Конец - Начало) / 1000;

   РезультСтрока = НСтр("ru = 'Результат процесса (количество строк = %КоличествоСтрок%, время выполнения = %ВремяВыполнения% с)'");
   РезультСтрока = СтрЗаменить(РезультСтрока, "%КоличествоСтрок%", Строка(КоличествоСтрок));
   РезультСтрока = СтрЗаменить(РезультСтрока, "%ВремяВыполнения%", Строка(ВремяВыполнения));

КонецПроцедуры

...Показать Скрыть


Любезно предоставил уважаемый StepByStep
в своей публикации
40. Юрий Осипов (yuraos) 21.03.13 16:27
(39)
к стати о птичках...

через COMОбъект("MSScriptControl.ScriptControl")
можно все остальные функции для работы с датами реализовать

без 1С-ного запроса и следовательно не напрягая сервер.

Там в скрипте используется класс с понятным назначением.
41. John Smith (PiccaHut001) 21.03.13 16:53
42. John Smith (PiccaHut001) 21.03.13 16:53
Давно мечтал о таком, теперь буду даты складывать.Автору респект.
43. Юрий Осипов (yuraos) 21.03.13 16:56
(26) andrewks,
возможно ты прав...
... хоть и не всегда действия элементарны.

Например год когда 365 дней, когда 366.
может где-нибудь аукнуться при вычислении разницы в годах.

но ведь в других средах программирования
делают зачем-то встроенные аналоги функций вроде
РазностьДат() и ДобавитьКДате()

и в языке запросов их 1С тоже сделала.


Если на небе зажигаются звезды, значит это кому-то надо...
44. Юрий Осипов (yuraos) 21.03.13 17:00
(35) AlexO,
ммммм...это комментарий от соседней функции залез в буфер
:)

а примерная реализация как в этом посте (39)
45. Юрий Осипов (yuraos) 21.03.13 17:07
ГОСПОДА!

А КУДА ПОДЕВАЛСЯ АВТОР СТАТЬИ (уважаемый vsuh) ???

Хоть бы один пост оставил.
:)

В личку что ли писать благодарности
за приятное общение на этой ветке ???
46. Алекс Ю (AlexO) 22.03.13 00:03
(45) yuraos,
Ушел писать обработки по ДОБАВИТЬКДАТЕ, найти запросом МАКСИМУМ и МИНИМУМ :)
47. Сергей Ожерельев (Поручик) 22.03.13 07:29
(45) Автор пошёл дальше читать Габеца и Гончарова - Простые примеры разработки.
48. andrewks 22.03.13 08:21
(40) yuraos, в то время, когда космические корабли бороздят просторы Вселенной грядёт стабильная 8.3, нужно использовать более универсальные механизмы, которые будут работать и на Win и на Lin.
поэтому я считаю, что +-*/ - наше всё. если лень вспоминать, сколько секунд в часе - можно накатать пару-тройку функций, чтобы потом их использовать
49. Наталия Степанова (Степанова Н.) 22.03.13 17:08
Для чего это вообще нужно
50. Юрий Осипов (yuraos) 22.03.13 19:26
(48) andrewks,
стабильная 1С-ка говоришь???
вот щастье то какое!!!
...
но боюсь я до этого не доживу.
;)))
51. Юрий Осипов (yuraos) 22.03.13 19:27
(49) Степанова Н.,
да так, особо не для чего.
...
так поболтать-почирикать.
;)
52. Юрий Осипов (yuraos) 22.03.13 19:29
(48) andrewks,
а насчет универсальности,
пожалуй,
с тобой соглашусь.
53. andrewks 22.03.13 22:53
(50) yuraos, будущее уже близко ))
Прикрепленные файлы:
54. Алекс Ю (AlexO) 23.03.13 00:18
(53) andrewks,
грядёт стабильная 8.3,

будущее уже близко ))

вашими планами - да мед пить 1с разрабатывать :))
55. Юрий Осипов (yuraos) 23.03.13 08:32
(54) AlexO,
интересно есть ли у кого статистика
по среднему количеству количеству выявленных багов допустим
за месяц или за год эксплуатации
по всем платформам для сравнения
8.0
8.1
8.2
ну и для новоявленного чуда-юда
8.3

???
56. andrewks 23.03.13 11:57
(54) AlexO, планы не мои :) я только разместил объяву ©
57. Алексей Алёхин (alexin08) 27.03.13 10:04
А для кадровика этот калькулятор очень даже интересен!
58. Марина Чирина (chmv) 11.08.14 09:05
59. Vladimir Glumov (Vovan58) 11.08.14 09:37
Как статью по поводу работы с датами - было бы интересно, а за деньги - стыдно!
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа