0. D.Gal 6 27.04.17 12:12 Сейчас в теме

Расчет возраста по дате рождения и текущей дате

Была задача - рассчитать возраст определенных лиц по дате их рождения. Решил поискать в интернете, как всегда множество мнений, множество реализаций, но, к сожалению, не встречал той статьи, где рассчитывалось количество полных лет, месяцев и дней.
Например: 28 лет, 3 месяца, 15 дней.

Решил заняться самостоятельно, и вот к чему это привело.

Перейти к публикации

Комментарии
Избранное Подписка Сортировка: Древо
1. FirePyres 43 28.04.17 11:52 Сейчас в теме
как то все сложно, у меня вот так получилось:
ВЫБРАТЬ
	&ТД КАК ТД,
	&ДР КАК ДР
ПОМЕСТИТЬ данные
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	РАЗНОСТЬДАТ(Данные.ДР, Данные.ТД, ГОД) + ВЫБОР
		КОГДА МЕСЯЦ(Данные.ДР) < МЕСЯЦ(Данные.ТД)
				ИЛИ МЕСЯЦ(Данные.ДР) = МЕСЯЦ(Данные.ТД)
					И ДЕНЬ(Данные.ДР) <= ДЕНЬ(Данные.ТД)
			ТОГДА 0
		ИНАЧЕ -1
	КОНЕЦ КАК Лет,
	МЕСЯЦ(Данные.ТД) - МЕСЯЦ(Данные.ДР) + ВЫБОР
		КОГДА МЕСЯЦ(Данные.ТД) - МЕСЯЦ(Данные.ДР) < 0
			ТОГДА 12
		ИНАЧЕ 0
	КОНЕЦ КАК Месяц,
	ВЫБОР
		КОГДА ДЕНЬ(Данные.ТД) - ДЕНЬ(Данные.ДР) >= 0
			ТОГДА ДЕНЬ(Данные.ТД) - ДЕНЬ(Данные.ДР)
		ИНАЧЕ ДЕНЬ(Данные.ТД) - ДЕНЬ(Данные.ДР) + РАЗНОСТЬДАТ(Данные.ТД, ДОБАВИТЬКДАТЕ(Данные.ТД, МЕСЯЦ, 1), ДЕНЬ)
	КОНЕЦ КАК День,
	Данные.ДР
ИЗ
	данные КАК Данные
Показать
user705522_constantin_h; maksa2005; autokono; +3 Ответить
2. D.Gal 6 28.04.17 16:08 Сейчас в теме
(1) как месяцев может быть 12?
9. sp18s 03.05.17 12:59 Сейчас в теме
(1) херня. вбейте
Имя параметра Значение параметра
ДР 05.05.2015 0:00:00
ТД 03.05.2017 0:00:00
и получите 1 лет и 29 дней.
10. Vlad_2008 13 03.05.17 14:07 Сейчас в теме
Странный запрос в (1) и процедура в (6) странная, и считает не правильно, для 27.04.2017 - 29.02.1988 выдала: "Лет: 29 Месяцев: 1 Дней: 30".

У меня запрос из трех строк выдает следующее:

27.04.2017 - 29.02.1988 = 29 лет 1 мес 27 дней
03.05.2017 - 29.02.1988 = 29 лет 2 мес 3 дня
11. Vlan 33 03.05.17 15:06 Сейчас в теме
(10) Для високосного года достаточно добавить одно условие и будет правильно.
	Лет = 0;
	Месяцев = 0;
	Дней = 0;
	ДатаР = Объект.ДатаРождения;
	Високосный = 0;
	Если Не День(ДобавитьМесяц(ДатаР,12)) = День(ДатаР) Тогда
		Високосный = 1;
		ДатаР = ДатаР - 60*60*24;
	КонецЕсли;
	Пока ДатаР <= Объект.ЛюбаяДата Цикл
		ДатаР = ДобавитьМесяц(ДатаР,1);
		Месяцев = Месяцев + 1;
	КонецЦикла;
	Месяцев = Месяцев-1;
	Лет = Цел(Месяцев/12);
	Месяцев = Месяцев-Лет*12;
	Дней = Цел((Объект.ЛюбаяДата - ДобавитьМесяц(ДатаР,-1))/(60*60*24))-Високосный;
	Объект.КоличествоДней = "Лет: "+Строка(Лет)+" Месяцев: "+Строка(Месяцев)+" Дней: "+Строка(Дней);
Показать

Между прочим, для 03.05.2017 - 29.02.1988 должно быть 29 лет 2 мес 4 дня, а не 3 дня, как у вас.
15. Vlad_2008 13 03.05.17 18:19 Сейчас в теме
(11) Ну я считал так:

29.02.1988 - 28.02.2017 = 29 лет
01.03.2017 - 30.04.2017 = 2 мес
01.05.2017 - 03.05.2017 = 3 дня

поправьте меня, где я потерял день?

В моем понимании, 29.02.1988 не должно считаться за день в этом расчете - это собсна день рождения, в этот день у человека "полный год", а вот со след. дня и пошел расчет ... "между прочим" )).

P.S.

А "високосный" Вы по прежнему считаете не правильно. А саму конструкцию проверки високосного я бы сделал так: "Год(ДатаР) % 4". Ваш способ, конечно, оригинален, я бы не додумался. Скорее всего я бы сделал так: День(КонецМесяца(ДатаР)) = 29 ... вау ))))))))

И еще, у Вас если д/р 29.02.1988, то Високосный = 1, а если 28.02.1988, то Високосный = 0 ... странно все ето ))) ужОс !!
16. Vlan 33 03.05.17 19:15 Сейчас в теме
(15) Високосный нужен только для 29.02, остальные дни считаются одинаково.
Логика расчета проста: каждое число следующего месяца, совпадающее с днем рождения дает полный месяц. Каждый следующий день, если месяц неполный, добавляется к дням. Именно так у вас "потерялся" один день. Полный месяц приходится на 29-е число. Затем идут 30,1,2,3. Итого 4 дня.
17. Vlad_2008 13 03.05.17 21:33 Сейчас в теме
(16) Да, Вы правы. Я зачем-то считал календарные месяцы, вместо реальных.

Переделал запрос, теперь все четко:
42. Vlad_2008 13 09.12.19 22:58 Сейчас в теме
(16) Может показалось ...

Каков возраст на 01.03.2019 в полных годах, если дата рождения будет 29.02.2008, покажет Ваш запрос ?

У меня Ваш запрос показал след. результаты:

ДатаРождения ТекущаяДата Условие ПолныхЛет

29.02.2008 0:00:00 01.03.2019 0:00:00 > 12
29.02.2008 0:00:00 01.03.2019 0:00:00 >= 12
43. Vlan 33 10.12.19 10:52 Сейчас в теме
(42) Не найду эту обработку. Чисто теоретически (по моим алгоритмам) должно быть 11 лет и 1 день.
44. Vlad_2008 13 10.12.19 16:39 Сейчас в теме
(43) Ой, не к тому сообщению написал ... это я к сообщению № 40

Мои расчеты показывают такой же результат )), а вот у ребят как-то странно!
18. borodatii 2 03.05.17 22:08 Сейчас в теме
(15) из википедии:
... год является високосным в двух случаях: либо он кратен 4, но при этом не кратен 100, либо кратен 400.
24. Vlad_2008 13 04.05.17 15:03 Сейчас в теме
(18)
... год является високосным в двух случаях: либо он кратен 4, но при этом не кратен 100, либо кратен 400.


... НЕ кратен 100, либо кратен 400 ...

Мой мозг не смог впитать сие ...
25. borodatii 2 04.05.17 15:29 Сейчас в теме
(24)
Год високосный в одном из двух случаев:
1) кратен 4, но при этом не кратен 100, например, 16, 96, 1996.
2) кратен 400, например 800, 2000.
Иначе - обычный, например, 100, 200, 300.
27. v3rter 04.05.17 16:02 Сейчас в теме
(25)
2) кратен 400, например 800, 2000.
Если уж совсем быть точными, григорианский календарь запустили 4 октября 1582 года, то есть кратные 400 года надо считать високосными если год>=1600. Но в нашем случае это, думаю, несущественно.
28. Vlad_2008 13 04.05.17 16:45 Сейчас в теме
(25) , (27)

Да, я видимо, застрял в юлианском календаре. Теперь вместо "Год % 4" буду делать
"ЭтоВисокосный = (Год % 400 = 0) ИЛИ (Год % 100 <> 0 И Год % 4 = 0)".


Кстати, в 1С 400,800,1200 - високосные, т.е. уже не важно, что запустили в 1582 году )).
3. FirePyres 43 29.04.17 05:55 Сейчас в теме
пример покажите,
я лично не вижу куска где такое возможно
МЕСЯЦ(Данные.ТД) - МЕСЯЦ(Данные.ДР) 
+ ВЫБОР
        КОГДА МЕСЯЦ(Данные.ТД) - МЕСЯЦ(Данные.ДР) < 0      ТОГДА 12

        ИНАЧЕ 0
    КОНЕЦ
4. D.Gal 6 29.04.17 13:20 Сейчас в теме
Да, невозможно, это я ошибся, только проблема с високосными годами осталась. Дни неправильно считает...
5. МимохожийОднако 129 03.05.17 07:42 Сейчас в теме
Полагаю в ЗУП уже есть подобные процедуры и функции
14. D.Gal 6 03.05.17 18:04 Сейчас в теме
(5) Можете скинуть реализацию из ЗУП?
19. МимохожийОднако 129 04.05.17 07:36 Сейчас в теме
6. Vlan 33 03.05.17 09:37 Сейчас в теме
А почему именно запросом получать дни?
Ведь гораздо проще соорудить такую, например, конструкцию:
	Лет = 0;
	Месяцев = 0;
	Дней = 0;
	ДатаР = Объект.ДатаРождения;
	Пока ДатаР <= ТекущаяДата() Цикл
		ДатаР = ДобавитьМесяц(ДатаР,1);
		Месяцев = Месяцев + 1;
	КонецЦикла;
	Месяцев = Месяцев-1;
	Лет = Цел(Месяцев/12);
	Месяцев = Месяцев-Лет*12;
	Дней = Цел((ТекущаяДата() - ДобавитьМесяц(ДатаР,-1))/(60*60*24));
	Объект.КоличествоДней = "Лет: "+Строка(Лет)+" Месяцев: "+Строка(Месяцев)+" Дней: "+Строка(Дней);
Показать
13. D.Gal 6 03.05.17 18:03 Сейчас в теме
(6) Я скажу, что такова была постановка задачи, решить которую надо запросом, в коде же модулей было бы значительно проще.
7. v3rter 03.05.17 10:07 Сейчас в теме
Вопрос с месяцами скорее методический - как складывать между собой два неполных месяца интервала и с чем сравнивать их суммарное количество дней.
8. v3rter 03.05.17 10:48 Сейчас в теме
Сравнивать их с 29, 30, 31, с количеством дней в месяце первой даты, с количеством дней в месяце второй даты, или с минимумом количества дней в месяцах обеих дат.
12. v3rter 03.05.17 17:40 Сейчас в теме
В экселе с разностью дат аналогичные проблемы http://excel2.ru/articles/funkciya-razndat-vychislenie-raznosti-dvuh-dat-v-dnyah-mesyacah-godah-v-ms-excel-razndat по ссылке варианты разностей с полными месяцами и с неполными, альтернативные формулы и немного обсуждения
20. Vlan 33 04.05.17 07:52 Сейчас в теме
Нашел и у себя ошибку. На 28-м числе дает неверные значения. Вот так поправил, теперь вроде с 29.02 все верно:
	Лет = 0; Месяцев = 0; Дней = 0; Високосный = Ложь;
	Сутки = 60*60*24;
	ДатаР = Объект.ДатаРождения;
	Если Не День(ДобавитьМесяц(ДатаР,12)) = День(ДатаР) Тогда
        Високосный = Истина;
    КонецЕсли;
    Пока ДатаР <= Объект.ЛюбаяДата Цикл
        ДатаР = ДобавитьМесяц(ДатаР,1);
		Если Високосный И Месяц(ДатаР)=3 
		И Не Год(Объект.ДатаРождения)= Год(ДатаР) Тогда
			ДатаР = ДатаР+Сутки;
		КонецЕсли;
        Месяцев = Месяцев + 1;
    КонецЦикла;
    Месяцев = Месяцев-1;
    Лет = Цел(Месяцев/12);
    Месяцев = Месяцев-Лет*12;
    Дней = Цел((Объект.ЛюбаяДата - ДобавитьМесяц(ДатаР,-1))/Сутки);
    Объект.КоличествоДней = "Лет: "+Строка(Лет)+" Месяцев: "+Строка(Месяцев)+" Дней: "+Строка(Дней);
Показать
23. Vlad_2008 13 04.05.17 14:56 Сейчас в теме
(20) Вчера гонял Ваш предыдущий вариант на ошибки и видел что на 28 числе они были, сейчас проверим новый вариант )).

Думаю, что и в Вашем варианте и в варианте из (22) будут ошибки, а думаю так, потому что Вы используете деление на "сутки". Чисто математически, очевидно, что при расчете за 1000 лет "что-то пойдет не так".
26. Vlan 33 04.05.17 15:44 Сейчас в теме
(23)Сомневаюсь, что за 1000 лет что-то поменяется. Если только календарь вдруг закончится, как у Майя. :-)
В моем алгоритме загвоздка была только в добавлении месяца с 29.01 до 29.02. 1C автоматом исправляла недопустимую дату на 28.02, если год не високосный. Достаточно было это обойти, чтобы программа заблистала во всей красе.
29. Vlad_2008 13 04.05.17 17:48 Сейчас в теме
(26) Проверил Ваш новый вариант, количество ошибок прежнее, просто они чуть сместились по дням, вот пара замеров:
Дата рождения: 31.12.1672 0:00:00,  период: 01.01.2017 0:00:00 - 31.12.2017 0:00:00
Ошибок = 336  ( 92,1% )

01.01.2017 = 344 - 00 - 01  /  344 - 00 - 01    344 - 00 - 02  !!!!!!!!!!!!
 --------------------------------------------------

Дата рождения: 29.02.1988 0:00:00,  период: 01.01.2017 0:00:00 - 31.12.2017 0:00:00
Ошибок = 30  ( 8,2% )

29.01.2017 = 28 - 11 - 00  /  28 - 11 - 00    28 - 11 - 01  !!!!!!!!!!!!
 --------------------------------------------------

[Дата текущая] = [расчет в запросе] / [расчет в коде]   [Ваш расчет]
Показать


На всякий случай, замечу, что я в своих расчетах не использую определение "високосности".

А Ваш цикл расчета месяцев всегда будет "грешить", т.к. конец месяца будет сбиваться не только в феврале и не обязательно в високосный год:

- 29.11.2016 + з мес = 28.02.2017 ( 29 -> 28 )
- 31.03.2017 + 3 мес = 30.06.2017 ( 31 -> 30 )

имеется в виду ДобавитьМесяц(Дата, 3).

Задайте ДР = 31.03.1975 и ДТ = 29.01.2017:

- старый = Лет: 41 Месяцев: 10 Дней: 1
- новый = Лет: 41 Месяцев: 9 Дней: 30

- д.быть = 29.01.2017 = 41 - 09 - 29.
30. Vlad_2008 13 04.05.17 19:30 Сейчас в теме
Тут вот еще замер производительности сделал, вариант (26) с циклом, явно проигрывает:

Период текущих дат: 01.01 - 31.12.2017

1) дата рождения: 29.02.1988

запрос     :  2  (  1,598 )
код        :  0  (  0,013 )
Инфостарт  :  1  (  1,235 )

2) дата рождения: 31.01.1700

запрос     :  2  (  1,606 )
код        :  0  (  0,013 )
Инфостарт  : 14  ( 13,164 )
Показать
31. Vlan 33 05.05.17 13:10 Сейчас в теме
(30) Ну, понятно, что на множественных циклах будет потеря времени. Тогда и алгоритм можно другой сделать, просто прибавляя по дню к полученному первоначально значению.
Я переделал свою обработку. Проверяйте.
&НаКлиенте
Процедура Рассчитать(Команда)
	Объект.КоличествоДней.Очистить();
	ДатаНач = Объект.ДатаНач;
	ЛюбаяДата = Объект.ЛюбаяДата;
	ДатаРождения = Объект.ДатаРождения;
	ЧислоДатаР = День(ДатаРождения);
	Сутки = 60*60*24;
	Пока ДатаНач <= ЛюбаяДата Цикл
		Лет = 0; Месяцев = 0; Дней = 0;
		ДатаР = ДатаРождения;
	    Пока ДатаР <= ДатаНач Цикл
			ДатаР = ПолучитьЧислоМесяца(ДатаР,ЧислоДатаР,1);
			Месяцев = Месяцев+1;
	    КонецЦикла;
	    Месяцев = Месяцев-1;
	    Лет = Цел(Месяцев/12);
	    Месяцев = Месяцев-Лет*12;
		ДатаР = ПолучитьЧислоМесяца(ДатаР,ЧислоДатаР,-1);
	    Дней = Цел((ДатаНач-ДатаР)/Сутки);
		Дни = Объект.КоличествоДней.Добавить();
		Дни.Дата = ДатаНач;
		Дни.Количество = "Лет: "+Строка(Лет)+" Месяцев: "+Строка(Месяцев)+" Дней: "+Строка(Дней);
		ДатаНач = ДатаНач + Сутки;
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Функция ПолучитьЧислоМесяца(ДатаР,Знач ЧислоДатаР,Смещение)
	День = ЧислоДатаР;
	Год = Год(ДатаР);
	Месяц = Месяц(ДатаР)+Смещение;
	Если Месяц > 12 Тогда
		Месяц = 1; 
		Год = Год + 1;
	ИначеЕсли Месяц = 0 Тогда
		Месяц = 12;
		Год = Год - 1;
	КонецЕсли;
	Пока День > 0 Цикл
		Попытка
			ДатаР = Дата(Год,Месяц,День);
			Прервать;
		Исключение
			День = День - 1;
		КонецПопытки;
	КонецЦикла;
	Возврат ДатаР;
КонецФункции
Показать

Остается открытым вопрос: от дня рождения на 31.05.2016 до 28.02.2017 будет полных 9 месяцев или 8 месяцев и 28 дней?
36. Vlad_2008 13 09.05.17 17:51 Сейчас в теме
(31) Я, думаю, что это 9 полных месяцев, т.к. "месячный" день рождения приходится именно на 28.02.2017.
21. Vlan 33 04.05.17 08:53 Сейчас в теме
А можно еще упростить, ведь сбивается общий расчет только для 29.02 при переходе с високосного года на обычный:
	Лет = 0; Месяцев = 0; Дней = 0;
	Сутки = 60*60*24;
	ДатаР = Объект.ДатаРождения;
    Пока ДатаР <= Объект.ЛюбаяДата Цикл
        ДатаР = ДобавитьМесяц(ДатаР,1);
		Если Месяц(ДатаР) = 3 И Не День(ДатаР) = День(Объект.ДатаРождения) Тогда
			ДатаР = ДатаР+Сутки;
		КонецЕсли;
        Месяцев = Месяцев+1;
    КонецЦикла;
    Месяцев = Месяцев-1;
    Лет = Цел(Месяцев/12);
    Месяцев = Месяцев-Лет*12;
    Дней = Цел((Объект.ЛюбаяДата-ДобавитьМесяц(ДатаР,-1))/Сутки);
    Объект.КоличествоДней = "Лет: "+Строка(Лет)+" Месяцев: "+Строка(Месяцев)+" Дней: "+Строка(Дней);
Показать
22. avart2006 04.05.17 09:47 Сейчас в теме
Вот мой реально работающий код в отчете:

Лет=0; Мес=0; Дн=0;	
РазобратьРазностьДат(ДатаКон, ДатаНач, Лет, Мес, Дн);
ЛетС = ФормаМножественногоЧисла("год","года","лет",Лет);	
МесС = ФормаМножественногоЧисла("месяц","месяца","месяцев",Мес);
ДнС = ФормаМножественногоЧисла("день","дня","дней",Дн);
СтрокаИтог = СокрЛП(?(Лет>0,Строка(Лет)+" "+ЛетС,"")+" "+?(Мес>0,Строка(Мес)+" "+МесС,"")+" "+Строка(дн)+" "+ДнС);

Функции:*****************************************************************************************************
Функция ФормаМножественногоЧисла(Слово1, Слово2, Слово3, Знач ЦелоеЧисло) 
	
	// Изменим знак целого числа, иначе отрицательные числа будут неправильно преобразовываться
	Если ЦелоеЧисло < 0 Тогда
		ЦелоеЧисло = -1 * ЦелоеЧисло;
	КонецЕсли;
	
	Если ЦелоеЧисло <> Цел(ЦелоеЧисло) Тогда 
		// для нецелых чисел - всегда вторая форма
		Возврат Слово2;
	КонецЕсли;
	
	// остаток
	Остаток = ЦелоеЧисло%10;
	Если (ЦелоеЧисло >10) И (ЦелоеЧисло<20) Тогда
		// для второго десятка - всегда третья форма
		Возврат Слово3;
	ИначеЕсли Остаток=1 Тогда
		Возврат Слово1;
	ИначеЕсли (Остаток>1) И (Остаток<5) Тогда
		Возврат Слово2;
	Иначе
		Возврат Слово3;
	КонецЕсли;

КонецФункции

Процедура РазобратьРазностьДат(Дата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))));
		КонецЕсли;
		
	КонецЕсли;
КонецПроцедуры
Показать
32. v3rter 05.05.17 14:10 Сейчас в теме
недокументированная Разндат() экселя считает, что 8
33. Vlan 33 05.05.17 14:26 Сейчас в теме
(32)Тогда получается, что полных 9 месяцев никогда не будет, что несколько странно. Придется еще костылей добавлять.
34. v3rter 05.05.17 14:29 Сейчас в теме
С 31.05.2016 по 01.03.2017эксель считает 9 полных месяцев, или я что-то не понял?
35. Vlan 33 05.05.17 14:34 Сейчас в теме
(34)У меня получается 0 дней, если числа дат совпадают. Следующая дата это уже n-месяцев + 1 день.
37. bashhhh 25 19.03.19 22:40 Сейчас в теме
Вроде можно проще:

ПолныхЛет = Год(ТекДата) - Год(ДатаРождения) 
					- ?(Месяц(ТекДата) < Месяц(ДатаРождения) 
						Или Месяц(ТекДата) = Месяц(ДатаРождения) И День(ТекДата) < День(ДатаРождения), 
 						1, 0);
maksa2005; Samarin; TSSV; katakuna; +4 Ответить
38. D.Gal 6 07.04.19 21:45 Сейчас в теме
(37) Вы когда этот комментарий писали, думали хоть, что в контексте моего запроса и задачи он вообще ничего значит. Зачем мне количество полных лет кодом, когда я написал, что задачу необходимо решать запросом было? Или Вы может не мне написали?
39. [4EPHbIYY_KOT] 37 28.06.19 11:59 Сейчас в теме
(38) Дали задачу в ЗУП 3.1 посчитать стаж работника на предприятии относительно даты приёма. Чтоб не рисовать новый код и отчёт, взял отчёт "Штатные сотрудники". Изменяя вариант, добавил в предприятии 3 пользовательских поля-выражения:

Лет, выражение:
РазностьДат([Дата приема], ТекущаяДата(), "ГОД") + Выбор
Когда Месяц([Дата приема]) < Месяц(ТекущаяДата()) Или Месяц([Дата приема]) = Месяц(ТекущаяДата()) И День([Дата приема]) <= День(ТекущаяДата())
Тогда 0
Иначе -1
Конец

Месяцев, выражение:
(РазностьДат(ДобавитьКДате([Дата приема], "Месяц", 1), ТекущаяДата(), "МЕСЯЦ") + Выбор
Когда День([Дата приема]) <= День(ТекущаяДата())
Тогда 1
Иначе 0
Конец) % 12

Дней, выражение:
Выбор
Когда День([Дата приема]) <= День(ТекущаяДата())
Тогда День(ТекущаяДата()) - День([Дата приема])
Иначе День(ТекущаяДата()) + РазностьДат([Дата приема], КонецПериода([Дата приема], "Месяц"), "День")
Конец + 1.

В детальных записях их вывел и сгруппировал в группу "Стаж на предприятии". Кадровики довольны.
Но это писал на языке СКД, в обычных запросах надо дописать несколько строк, чтобы получить остаток от деления на 12 при вычислении полных месяцев, а текущую дату втыкать параметром в запрос. Думаю, в решении Вашей задачи вполне может помочь.
40. Zurfik 09.12.19 05:34 Сейчас в теме
Вот моя реализация вашей задачи, прошу закрепить, она считает полное количество лет, но можно легко переделать чтобы еще количество месяцев и дней выводила. Встал вопрос решить в запросе т.к. не нашел пришлось самому писать:
Выбор Когда ДеньГода(ДОБАВИТЬКДАТЕ(&ДатаРождения, День, РАЗНОСТЬДАТ(&ДатаРождения, &ТекущаяДата, День)))+(ДЕНЬГОДА(КонецПериода(&ДатаРождения,Год))-ДЕНЬГОДА(&ДатаРождения))>ДЕНЬГОДА(КонецПериода(&ТекущаяДата,Год))
	Тогда РАЗНОСТЬДАТ(&ДатаРождения, &ТекущаяДата, Год)+1
	Иначе РАЗНОСТЬДАТ(&ДатаРождения, &ТекущаяДата, Год) Конец КАК ПолныхЛет
41. Zurfik 09.12.19 07:14 Сейчас в теме
(40)
Правильнее будет заменить ">" на ">=", тогда если день рождения совпадет с текущей датой, то количество полных лет будет максимальное уже на эту дату.
45. Vlad_2008 13 10.12.19 16:40 Сейчас в теме
(40) Может показалось ...

Каков возраст на 01.03.2019 в полных годах, если дата рождения будет 29.02.2008, покажет Ваш запрос ?

У меня Ваш запрос показал след. результаты:

ДатаРождения ____ ТекущаяДата _____ Условие ____ ПолныхЛет

29.02.2008 0:00:00 ___ 01.03.2019 0:00:00 ___ > ___ 12
29.02.2008 0:00:00 ___ 01.03.2019 0:00:00 ___ >= ___ 12
46. Zurfik 11.12.19 04:11 Сейчас в теме
(45) Попробуйте вот так. Должно все правильно считать.
Выбор Когда ДеньГода(ДОБАВИТЬКДАТЕ(&ДатаРождения, День, РАЗНОСТЬДАТ(&ДатаРождения, &ТекущаяДата, День)))+(ДЕНЬГОДА(КонецПериода(&ДатаРождения,Год))-ДЕНЬГОДА(&ДатаРождения))>=ДЕНЬГОДА(КонецПериода(&ТекущаяДата,Год))
    Тогда РАЗНОСТЬДАТ(&ДатаРождения, &ТекущаяДата, Год)
    Иначе РАЗНОСТЬДАТ(&ДатаРождения, &ТекущаяДата, Год)-1 Конец КАК ПолныхЛет

ДатаРождения: 29.02.2019
ТекущаяДата: 28.02.2019
Тоже считает правильно, как полных - 11лет.
47. BigB 178 11.12.19 15:49 Сейчас в теме
Я вот тут уже публиковал свой запрос. Повторю его здесь:
ВЫБРАТЬ
    Годы.Лет КАК Лет,
    РАЗНОСТЬДАТ(Годы.ДХ, &Д2, МЕСЯЦ) - Годы.Х КАК Месяцев,
    РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Годы.ДХ, МЕСЯЦ, РАЗНОСТЬДАТ(Годы.ДХ, &Д2, МЕСЯЦ) - Годы.Х), &Д2, ДЕНЬ) КАК Дней
ИЗ
    (ВЫБРАТЬ
        РАЗНОСТЬДАТ(&Д1, &Д2, ГОД) - ВЫБОР
            КОГДА ДОБАВИТЬКДАТЕ(&Д1, ГОД, РАЗНОСТЬДАТ(&Д1, &Д2, ГОД)) > &Д2
                ТОГДА 1
            ИНАЧЕ 0
        КОНЕЦ КАК Лет,
        ДОБАВИТЬКДАТЕ(&Д1, ГОД, РАЗНОСТЬДАТ(&Д1, &Д2, ГОД) - ВЫБОР
                КОГДА ДОБАВИТЬКДАТЕ(&Д1, ГОД, РАЗНОСТЬДАТ(&Д1, &Д2, ГОД)) > &Д2
                    ТОГДА 1
                ИНАЧЕ 0
            КОНЕЦ) КАК ДХ,
        ВЫБОР
            КОГДА ДЕНЬ(&Д1) > ДЕНЬ(&Д2)
                ТОГДА 1
            ИНАЧЕ 0
        КОНЕЦ КАК Х) КАК Годы
Показать
48. Zurfik 12.12.19 05:36 Сейчас в теме
(47) На датах 29.02.2008 - 28.02.2019
Он показывает 11лет -1 месяц 31 день.
Это дата кстати на многих онлайн калькуляторах расчета возраста даёт очень интересные результаты)))
49. Vlad_2008 13 12.12.19 12:00 Сейчас в теме
Что-то, за два года, мы так и не увидели "правильный" запрос по расчету возраста в Год-Месяц-День ... будем ждать дальше ))

Да, онлайн калькуляторы тоже смотрел, ржал, почти все показывают какую-то ерунду.
51. sssss_aaaaa_2011 04.02.20 21:14 Сейчас в теме
(49)
Давно не заглядывал на инфостарт, а тут такое...
Одни все изобретают вечный двигатель, а прогеры пишут расчет разницы дат в годах, месяцах и днях...
До сих пор никто из тусующихся тут, похоже, еще не знает, что НЕТ одного алгоритма расчета разницы дат ибо нет одной размерности у таких единиц измерения как год и месяц. Вы в каких годах и месяцах собрались все это мерить? В средних, максимальных, минимальных, фиксированных, учетных, условных?
Есть несколько специальных алгоритмов для конкретных случаев (стажи, возрасты, сроки и т.д.), но все они считают по-разному. И правила их расчета уже давно придуманы, и устанавливаются не прогерами, а соответствующими правилами и инструкциями. И даже один, вроде бы, период, например, с 01.01 по 29.03, при расчете по одному алгоритму может давать разные результаты в разные годы.
52. Vlad_2008 13 07.02.20 15:43 Сейчас в теме
С (49) соглашусь, что в разные годы результаты могут отличаться, смотря Что и Как считаем.

В нашем случае мы считаем возраст в полных Годах - Месяцах - Днях. Т.е. ни каких средних, фиксированных и прочих, только строго по календарю.


(50)
"ВЫБРАТЬ
| СУММА(Объед.Года) КАК Года,
| СУММА(Объед.Месяцы) КАК Месяцы,
...
|ИЗ
| ВТ_Итог КАК ВТ_Итог"


Запрос как-то напугал меня, решил его проверить.

Мои расчеты:

- дата рождения = 01.02.2020
- дата текущая = 29.02.2020

- Лет = 0
- Месяцев = 0
- Дней = 28

Я с этим согласен, день рожденья наступит только 01.03.2020 и для этой даты мой расчет показывает:

- Лет = 0
- Месяцев = 1
- Дней = 0

Ну и тут не поспоришь.

Ваш запрос:

- дата рождения = 01.02.2020
- дата текущая = 29.02.2020

- Лет = 0
- Месяцев = 1
- Дней = 0

- дата рождения = 01.02.2020
- дата текущая = 01.03.2020

- Лет = 0
- Месяцев = 1
- Дней = 1

В обоих случаях НЕ ПРАВИЛЬНО, по моему убеждению, т.к. мы считаем ПОЛНЫЕ г/м/д и полный месяц будет 01.03 в 00:00:00, а не 29.02 в 23:59:59.

А ведь всего три строчки кода ... бум ждать ...
53. sssss_aaaaa_2011 07.02.20 16:02 Сейчас в теме
(52) "В нашем случае мы считаем возраст в полных Годах - Месяцах - Днях. Т.е. ни каких средних, фиксированных и прочих, только строго по календарю."
И где хоть один пример с календарем? Все же пытаются найти формулу, не использующую календарь. Для расчета по календарю надо идти по календарю и считать количество границ перехода на новую единицу измерения, то есть циклом. Но ведь как раз от цикла хотят избавиться.
Про необычность результатов расчетов с использованием РазностьДат(DateDiff) - похоже народ совершенно не читает доку по этим функциям. Или читают только первые предложения.
55. kasper076 49 07.02.20 17:07 Сейчас в теме
(53) Мой запрос именно по календарю и считает.
56. sssss_aaaaa_2011 07.02.20 17:54 Сейчас в теме
(55)Кто вам сказал такую чушь? Арифметические операции с частями даты вдруг стали привязаны к календарю? И перестали быть частью некоей формулы?
57. kasper076 49 07.02.20 19:20 Сейчас в теме
(56) По вашему день(конецпериода(Дата, месяц)) это арифметическая операция?
60. sssss_aaaaa_2011 10.02.20 09:34 Сейчас в теме
(57)Это получение некоего числа, которое к конкретной дате уже не имеет никакого отношения. Как и все дальнейшие операции с ним.
63. kasper076 49 10.02.20 14:08 Сейчас в теме
(60)
Это получение некоего числа, которое к конкретной дате уже не имеет никакого отношения. Как и все дальнейшие операции с ним.

Это получение не некоего числа. Это получения числа дней в конкретном месяце согласно календарю.

А для чего тогда нужен календарь? Разве количество месяцев нельзя посчитать с помощью арифметической операции? Или для подсчета количества дней обязательно необходим календарь?
68. sssss_aaaaa_2011 11.02.20 09:16 Сейчас в теме
(63)"Это получение не некоего числа. Это получения числа дней в конкретном месяце согласно календарю."
Да не важно согласно чему оно получено, важно то, что это число, просто число, каких в календаре вагон и маленькая тележка.

"Разве количество месяцев нельзя посчитать с помощью арифметической операции?"
Да, вот именно эта мысль как-то очень туго некоторыми понимаема. Месяц - самая неравномерная единица измерения. Почему и спрашивали - в каких месяцах собрались считать? В январях или февралаях? А если в февралях - то в каких, обычных или високосных? Арифметические операции предполагают использование единиц измерения, которые не меняются по величине в зависимости от места их применения. Что их очень сильно отличает от месяца.

Вот немного для понимания сути вопроса:
Как получить разницу двух дат в формате: лет, месяцев, дней
54. kasper076 49 07.02.20 16:41 Сейчас в теме
(52) ДатаНачала это первый полный день периода, Дата Окончания это последний полный день периода, поскольку считаем с точностью до дня. Если на форме вывести поле стандартного периода, то дата окончания в нем будет включаться в него полностью, а не по принципу Новый Граница(ДатаОкончания, ВидГраницы.Исключая). Ведь так?
полный месяц будет 01.03 в 00:00:00, а не 29.02 в 23:59:59

Т.е. секунда которая прошла с 01.02.20 00:00:00 по 01.02.20 00:00:01 не учитывается?
По Вашей логике с 00 секунд до следующих 00 секунд прошло 9 секунд?
0__1__2__3__4__5__6__7__8__9__0
|1| |2| |3| |4| |5| |6| |7| |8| |9| |10|
58. Vlad_2008 13 09.02.20 20:09 Сейчас в теме
(54) Я все понял, мы говорим об одном и том же, просто у нас разная трактовка параметров передаваемых в запрос. В нашем примере, для дня рождения 01.02 найти возраст на 01.03 (эта дата не участвует в расчете) надо:

Ваш вариант:

ДатаНачала = 01.02.2020
ДатаОкончания = 29.02.2020

Ответ: 1 месяц 0 дней - Правильно!

Мой вариант

ДатаРождения = 01.02.2020
ДатаТекущая = 01.03.2020

Ответ: 1 месяц 0 дней - Правильно!

Т.е. у нас разная логика в расчетах, и когда я "обозвал" Ваш запрос неправильным, я думал в своей логике, извиняюсь, был не прав.

Используя ДатаТекущая мой запрос получается проще и ни каких проблем, кои озвучены в (53), при использовании функции РазностьДат не возникает. Даже применительно к нашему примеру, расчет будет выглядеть очень просто:

РАЗНОСТЬДАТ(01.02, 01.03, МЕСЯЦ) = 1

не надо лишних проверок и вычислений.
62. kasper076 49 10.02.20 11:53 Сейчас в теме
(58)
Используя ДатаТекущая мой запрос получается проще и ни каких проблем
неоднократно ссылаетесь на некий ваш запрос, но в теме я его текст не нашел. Можете его тут показать?
50. kasper076 49 04.02.20 17:44 Сейчас в теме
	"ВЫБРАТЬ
	|	СУММА(Объед.Года) КАК Года,
	|	СУММА(Объед.Месяцы) КАК Месяцы,
	|	СУММА(Объед.Дни) КАК Дни
	|ПОМЕСТИТЬ ВТ_Итог
	|ИЗ
	|	(ВЫБРАТЬ
	|		0 КАК Года,
	|		ВЫБОР
	|			КОГДА МЕСЯЦ(&ДатаОкончания) - МЕСЯЦ(&ДатаНачала) > 1
	|				ТОГДА МЕСЯЦ(&ДатаОкончания) - МЕСЯЦ(&ДатаНачала) - 1
	|			ИНАЧЕ 0
	|		КОНЕЦ КАК Месяцы,
	|		ВЫБОР
	|			КОГДА МЕСЯЦ(&ДатаНачала) = МЕСЯЦ(&ДатаОкончания)
	|				ТОГДА ДЕНЬ(&ДатаОкончания) - ДЕНЬ(&ДатаНачала)
	|			ИНАЧЕ ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + ДЕНЬ(&ДатаОкончания)
	|		КОНЕЦ + 1 КАК Дни
	|	ГДЕ
	|		ГОД(&ДатаНачала) = ГОД(&ДатаОкончания)
	|	
	|	ОБЪЕДИНИТЬ ВСЕ
	|	
	|	ВЫБРАТЬ
	|		0,
	|		ВЫБОР
	|			КОГДА ГОД(&ДатаНачала) = ГОД(&ДатаОкончания)
	|				ТОГДА ВЫБОР
	|						КОГДА МЕСЯЦ(&ДатаНачала) = МЕСЯЦ(&ДатаОкончания)
	|							ТОГДА МЕСЯЦ(&ДатаНачала)
	|						ИНАЧЕ МЕСЯЦ(&ДатаОкончания) - 1
	|					КОНЕЦ
	|			ИНАЧЕ 12
	|		КОНЕЦ - МЕСЯЦ(&ДатаНачала),
	|		ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1
	|	ГДЕ
	|		ГОД(&ДатаНачала) <> ГОД(&ДатаОкончания)
	|	
	|	ОБЪЕДИНИТЬ ВСЕ
	|	
	|	ВЫБРАТЬ
	|		ГОД(&ДатаОкончания) - ГОД(&ДатаНачала) - 1,
	|		0,
	|		0
	|	ГДЕ
	|		ГОД(&ДатаОкончания) - ГОД(&ДатаНачала) > 1
	|	
	|	ОБЪЕДИНИТЬ ВСЕ
	|	
	|	ВЫБРАТЬ
	|		0,
	|		МЕСЯЦ(&ДатаОкончания) - 1,
	|		ДЕНЬ(&ДатаОкончания)
	|	ГДЕ
	|		ГОД(&ДатаОкончания) - ГОД(&ДатаНачала) > 0) КАК Объед
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	ВТ_Итог.Года + ВЫБОР
	|		КОГДА ВТ_Итог.Месяцы + ВЫБОР
	|				КОГДА ВТ_Итог.Дни >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
	|					ТОГДА 1
	|				ИНАЧЕ 0
	|			КОНЕЦ >= 12
	|			ТОГДА 1
	|		ИНАЧЕ 0
	|	КОНЕЦ КАК Года,
	|	ВТ_Итог.Месяцы + ВЫБОР
	|		КОГДА ВТ_Итог.Дни >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
	|			ТОГДА 1
	|		ИНАЧЕ 0
	|	КОНЕЦ - ВЫБОР
	|		КОГДА ВТ_Итог.Месяцы + ВЫБОР
	|				КОГДА ВТ_Итог.Дни >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
	|					ТОГДА 1
	|				ИНАЧЕ 0
	|			КОНЕЦ >= 12
	|			ТОГДА 12
	|		ИНАЧЕ 0
	|	КОНЕЦ КАК Месяцы,
	|	ВТ_Итог.Дни - ВЫБОР
	|		КОГДА ВТ_Итог.Дни >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
	|			ТОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
	|		ИНАЧЕ 0
	|	КОНЕЦ КАК Дни
	|ИЗ
	|	ВТ_Итог КАК ВТ_Итог"
Показать
59. Vlad_2008 13 09.02.20 23:14 Сейчас в теме
(50) По поводу запроса, как писал выше - он меня пугает, громоздкий какой-то, куча объединений, временная таблица. Хотел его прогнать на правильность и сделать замеры, но ... при проверке еще одной даты получил результаты, которые считаю неправильными.

Для сравнения берем два примера:

1) дата рождения = 01.02.2020 (был уже в сообщениях выше)
2) дата рождения = 01.02.2000

Считаем возраст на 01.03.2020 (эта дата не включается в расчет)

Мои расчеты:

1.1) дата рождения = 01.02.2020
1.2) дата текущая = 01.03.2020

Ответ: 0 лет 1 месяц 0 дней

2.1) дата рождения = 01.02.2000
2.2) дата текущая = 01.03.2020

Ответ: 20 лет 1 месяц 0 дней

Все ответы считаю правильными.

Ваш запрос:

1.1) дата начала = 01.02.2020
1.2) дата окончания = 29.02.2020

Ответ: 0 лет 1 месяц 0 дней

2.1) дата начала = 01.02.2000
2.2) дата окончания = 29.02.2020

Ответ: 20 лет 0 месяцев 29 дней

Последний ответ странный

И еще один расчет по Вашему запросу для даты следующей за 29.02.2020, т.е. 01.03. 2020 (прошел всего ОДИН день)

3.1) дата начала = 01.02.2000
3.2) дата окончания = 01.03.2020

Ответ: 20 лет 1 месяц 1 день.

Результат странный, добавили всего один день, но в ответе видим что и месяц прошел, и день еще один появился.

Пока делаю вывод что для даты рождения 01.02.2000 Ваш запрос считает неправильно.

Жду Ваших комментариев ...
61. kasper076 49 10.02.20 10:09 Сейчас в теме
(59)
РАЗНОСТЬДАТ(01.02, 01.03, МЕСЯЦ) = 1

С таким же успехом РАЗНОСТЬДАТ(29.02, 01.03, МЕСЯЦ) = 1


2.1) дата начала = 01.02.2000
2.2) дата окончания = 29.02.2020
Ответ: 20 лет 0 месяцев 29 дней

С этим согласен.


3.1) дата начала = 01.02.2000
3.2) дата окончания = 01.03.2020
Ответ: 20 лет 1 месяц 1 день.

Тут что не так? С 01.02.2000 по 31.01.2020 (включительно) прошло ровно 20 лет. Затем прошел февраль 2020 года и один день марта.

Если пользователь указывает период с 01.02.2000 по 01.03.2020, то он предполагает, что 01.03.2020 входит в этот период.

Вот текст запроса в котором наглядно виден алгоритм расчета:
"ВЫБРАТЬ
|	0 КАК Года,
|	ВЫБОР
|		КОГДА НАЧАЛОПЕРИОДА(&ДатаНачала, МЕСЯЦ) = &ДатаНачала
|				И КОНЕЦПЕРИОДА(&ДатаОкончания, МЕСЯЦ) = &ДатаОкончания
|			ТОГДА 1
|		ИНАЧЕ 0
|	КОНЕЦ КАК Месяцы,
|	ВЫБОР
|		КОГДА НАЧАЛОПЕРИОДА(&ДатаНачала, МЕСЯЦ) = &ДатаНачала
|				И КОНЕЦПЕРИОДА(&ДатаОкончания, МЕСЯЦ) = &ДатаОкончания
|			ТОГДА 0
|		ИНАЧЕ ДЕНЬ(&ДатаОкончания) - ДЕНЬ(&ДатаНачала) + 1
|	КОНЕЦ КАК Дни
|ПОМЕСТИТЬ ВТ_ОдинГодОдинМесяц
|ГДЕ
|	ГОД(&ДатаНачала) = ГОД(&ДатаОкончания)
|	И МЕСЯЦ(&ДатаОкончания) = МЕСЯЦ(&ДатаНачала)
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
|	0 КАК Года,
|	0 КАК Месяцы,
|	ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) КАК Дни
|ПОМЕСТИТЬ ВТ_ОдинГодКрайниеМесяцы
|ГДЕ
|	ГОД(&ДатаНачала) = ГОД(&ДатаОкончания)
|	И МЕСЯЦ(&ДатаОкончания) - МЕСЯЦ(&ДатаНачала) > 0
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
|	0 КАК Года,
|	ВЫБОР
|		КОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) + ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаОкончания, МЕСЯЦ))
|			ТОГДА 1
|		ИНАЧЕ 0
|	КОНЕЦ КАК Месяцы,
|	ВЫБОР
|		КОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) + ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаОкончания, МЕСЯЦ))
|			ТОГДА -ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаОкончания, МЕСЯЦ))
|		ИНАЧЕ 0
|	КОНЕЦ КАК Дни
|ПОМЕСТИТЬ ВТ_ОдинГодКрайниеМесяцыДниВМесяцы
|ИЗ
|	ВТ_ОдинГодКрайниеМесяцы КАК ВТ_ОдинГодКрайниеМесяцы
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|	0,
|	ВЫБОР
|		КОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
|			ТОГДА 1
|		ИНАЧЕ 0
|	КОНЕЦ,
|	ВЫБОР
|		КОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
|			ТОГДА -ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
|		ИНАЧЕ 0
|	КОНЕЦ
|ИЗ
|	ВТ_ОдинГодКрайниеМесяцы КАК ВТ_ОдинГодКрайниеМесяцы
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
|	0 КАК Года,
|	МЕСЯЦ(&ДатаОкончания) - МЕСЯЦ(&ДатаНачала) - 1 КАК Месяцы,
|	0 КАК Дни
|ПОМЕСТИТЬ ВТ_ОдинГодРазныеМесяцы
|ГДЕ
|	ГОД(&ДатаНачала) = ГОД(&ДатаОкончания)
|	И МЕСЯЦ(&ДатаОкончания) - МЕСЯЦ(&ДатаНачала) > 1
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
|	0 КАК Года,
|	12 - МЕСЯЦ(&ДатаНачала) + (МЕСЯЦ(&Датаокончания) - 1) КАК Месяцы,
|	ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) КАК Дни
|ПОМЕСТИТЬ ВТ_КрайниеГода
|ГДЕ
|	ГОД(&ДатаОкончания) - ГОД(&ДатаНачала) > 0
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
|	0 КАК Года,
|	ВЫБОР
|		КОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
|			ТОГДА 1
|		ИНАЧЕ 0
|	КОНЕЦ КАК Месяцы,
|	ВЫБОР
|		КОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
|			ТОГДА -ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ))
|		ИНАЧЕ 0
|	КОНЕЦ КАК Дни
|ПОМЕСТИТЬ ВТ_КрайниеГодаДниВМесяцы
|ИЗ
|	ВТ_КрайниеГода КАК ВТ_КрайниеГода
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|	0,
|	ВЫБОР
|		КОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) + ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаОкончания, МЕСЯЦ))
|			ТОГДА 1
|		ИНАЧЕ 0
|	КОНЕЦ,
|	ВЫБОР
|		КОГДА ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) - ДЕНЬ(&ДатаНачала) + 1 + ДЕНЬ(&ДатаОкончания) >= ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаНачала, МЕСЯЦ)) + ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаОкончания, МЕСЯЦ))
|			ТОГДА -ДЕНЬ(КОНЕЦПЕРИОДА(&ДатаОкончания, МЕСЯЦ))
|		ИНАЧЕ 0
|	КОНЕЦ
|ИЗ
|	ВТ_КрайниеГода КАК ВТ_КрайниеГода
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
|	ГОД(&ДатаОкончания) - ГОД(&ДатаНачала) - 1 КАК Года,
|	0 КАК Месяцы,
|	0 КАК Дни
|ПОМЕСТИТЬ ВТ_РазныеГода
|ГДЕ
|	ГОД(&ДатаОкончания) - ГОД(&ДатаНачала) > 1
|;
|
|////////////////////////////////////////////////////////////­////////////////////
|ВЫБРАТЬ
|	ВЫБОР
|		КОГДА СУММА(Объед.Месяцы) >= 12
|			ТОГДА СУММА(Объед.Года) + МАКСИМУМ(1)
|		ИНАЧЕ СУММА(Объед.Года)
|	КОНЕЦ КАК Года,
|	ВЫБОР
|		КОГДА СУММА(Объед.Месяцы) >= 12
|			ТОГДА СУММА(Объед.Месяцы) - МАКСИМУМ(12)
|		ИНАЧЕ СУММА(Объед.Месяцы)
|	КОНЕЦ КАК Месяцы,
|	СУММА(Объед.Дни) КАК Дни
|ИЗ
|	(ВЫБРАТЬ
|		ВТ_ОдинГодОдинМесяц.Года КАК Года,
|		ВТ_ОдинГодОдинМесяц.Месяцы КАК Месяцы,
|		ВТ_ОдинГодОдинМесяц.Дни КАК Дни
|	ИЗ
|		ВТ_ОдинГодОдинМесяц КАК ВТ_ОдинГодОдинМесяц
|	
|	ОБЪЕДИНИТЬ ВСЕ
|	
|	ВЫБРАТЬ
|		ВТ_ОдинГодКрайниеМесяцы.Года,
|		ВТ_ОдинГодКрайниеМесяцы.Месяцы,
|		ВТ_ОдинГодКрайниеМесяцы.Дни
|	ИЗ
|		ВТ_ОдинГодКрайниеМесяцы КАК ВТ_ОдинГодКрайниеМесяцы
|	
|	ОБЪЕДИНИТЬ ВСЕ
|	
|	ВЫБРАТЬ
|		ВТ_ОдинГодКрайниеМесяцыДниВМесяцы.Года,
|		ВТ_ОдинГодКрайниеМесяцыДниВМесяцы.Месяцы,
|		ВТ_ОдинГодКрайниеМесяцыДниВМесяцы.Дни
|	ИЗ
|		ВТ_ОдинГодКрайниеМесяцыДниВМесяцы КАК ВТ_ОдинГодКрайниеМесяцыДниВМесяцы
|	
|	ОБЪЕДИНИТЬ ВСЕ
|	
|	ВЫБРАТЬ
|		ВТ_ОдинГодРазныеМесяцы.Года,
|		ВТ_ОдинГодРазныеМесяцы.Месяцы,
|		ВТ_ОдинГодРазныеМесяцы.Дни
|	ИЗ
|		ВТ_ОдинГодРазныеМесяцы КАК ВТ_ОдинГодРазныеМесяцы
|	
|	ОБЪЕДИНИТЬ ВСЕ
|	
|	ВЫБРАТЬ
|		ВТ_КрайниеГода.Года,
|		ВТ_КрайниеГода.Месяцы,
|		ВТ_КрайниеГода.Дни
|	ИЗ
|		ВТ_КрайниеГода КАК ВТ_КрайниеГода
|	
|	ОБЪЕДИНИТЬ ВСЕ
|	
|	ВЫБРАТЬ
|		ВТ_КрайниеГодаДниВМесяцы.Года,
|		ВТ_КрайниеГодаДниВМесяцы.Месяцы,
|		ВТ_КрайниеГодаДниВМесяцы.Дни
|	ИЗ
|		ВТ_КрайниеГодаДниВМесяцы КАК ВТ_КрайниеГодаДниВМесяцы
|	
|	ОБЪЕДИНИТЬ ВСЕ
|	
|	ВЫБРАТЬ
|		ВТ_РазныеГода.Года,
|		ВТ_РазныеГода.Месяцы,
|		ВТ_РазныеГода.Дни
|	ИЗ
|		ВТ_РазныеГода КАК ВТ_РазныеГода) КАК Объед"
Показать


Для периода 01.02.2000 - 29.02.2020 выдает верный результат.
При желании можно переписать запрос без использования временных таблиц, но тогда оч сильно пострадает читабельность.
Прикрепленные файлы:
64. Vlad_2008 13 10.02.20 16:07 Сейчас в теме
(61)


3.1) дата начала = 01.02.2000
3.2) дата окончания = 01.03.2020
Ответ: 20 лет 1 месяц 1 день.

Тут что не так? С 01.02.2000 по 31.01.2020 (включительно) прошло ровно 20 лет. Затем прошел февраль 2020 года и один день марта.


Ответ тут правильный, под странностью имел ввиду его отличие от расчета 01.02.2000 - 29.02.2020 на два дня. Может не удачно выразился.

Ну и хотел намекнуть, что надо стараться проверять свои разработки перед тем как выкладывать.

Один из способов проверки такого запроса, как раз состоит в сравнении результатов расчетов на конкретный день и предыдущий, т.е. должна быть единичка. Я так проверял свой, например за год, выполнял запрос на каждый день года.
kasper076; +1 Ответить
65. kasper076 49 10.02.20 17:45 Сейчас в теме
(64)
отличие от расчета 01.02.2000 - 29.02.2020 на два дня

Почему на 2 дня?

2.1) дата начала = 01.02.2000
2.2) дата окончания = 29.02.2020

Ответ: 20 лет 0 месяцев 29 дней

В феврале 2020-го года 29 дней. Т.е. ошибка в том, что запрос вернул 29 дней, а не в 1 месяц. После добавления одного дня ошибка исчезла.
66. Vlad_2008 13 11.02.20 04:17 Сейчас в теме
(61)

Проверял запрос из (61) для интервала 01.02.2000 - 29.02.2020 теперь все правильно.

Бьемся дальше ... проверил еще несколько дат:

(варианты кстати, интересны тем, что люди прожили разное количество дней, но возраст у них одинаковый, это для тех кто любит делить разность дней на среднее количество дней в месяце и т.п.)

Мои расчеты

1) дата рождения = 30.01.2000
1) дата текущая = 01.07.2000 (эта дата не участвует в расчетах)
1) ответ = 5 месяцев 1 день

2) дата рождения = 31.01.2000
2) дата текущая = 01.07.2000 (эта дата не участвует в расчетах)
2) ответ = 5 месяцев 1 день

Ваш запрос

1) дата начала = 30.01.2000
1) дата окончания = 30.06.2000
1) ответ = 5 месяцев 1 день

2) дата начала = 31.01.2000
2) дата окончания = 30.06.2000
2) ответ = 5 месяцев 0 дней

Последний ответ неправильный.

неоднократно ссылаетесь на некий ваш запрос, но в теме я его текст не нашел. Можете его тут показать?


Возможно, но позже, дадим еще кому-то высказаться, ну и, хочется увидеть запрос который считает без ошибок ))
67. kasper076 49 11.02.20 07:53 Сейчас в теме
(66) Так оба же не верные. На работу приеду проверю.
69. sssss_aaaaa_2011 11.02.20 09:24 Сейчас в теме
(66)
хочется увидеть запрос который считает без ошибок ))

Господа, вас не наводит ни на какие мысли тот факт, что календарями и датами человечество пользуется уже не одну тысячу лет, но до сих пор тоже человечество не придумало того самого способа получения дат в формате лет, месяцев, дней, который вы тут пытаетесь создать? Или вы такой уже видели и сейчас решили заняться изобретением велосипеда? Вам не кажется, что ситуация очень сильно напоминает ситуацию с вечным двигателем? Все не против бы его увидеть, некоторые даже пытались/пытаются его сделать, как всегда чего-то вот совсем чуть-чуть доработать, почти работает, но воз и ныне там.
73. Vlad_2008 13 11.02.20 14:19 Сейчас в теме
К (69), может и велосипед, но решение текущей задачи есть. Внутри платформы есть функции, которые надо использовать (РазностьДат, ДобавитьКДате, ДобавитьМесяц) и все будет нормально, в этих функциях учтено все что нужно.

Но вот большая часть разработчиков пытается написать "свой" алгоритм, и, натыкается на грабли ...

В сообщениях выше писал, что не надо делить, не надо учитывать високосность и прочее, надо "правильно" пользоваться штатными функциями.

Вот приводил примерчик, в нем намек, не очевидный, но все же ... сравните две записи:

РАЗНОСТЬДАТ(01.02, 01.03, МЕСЯЦ) = 1 из (59)

РАЗНОСТЬДАТ(29.02, 01.03, МЕСЯЦ) = 1 из (60)

в какой-то, получаемый результат имеет весьма расплывчатый смысл и вряд-ли может быть полезен для дальнейших расчетов.
78. sssss_aaaaa_2011 11.02.20 16:10 Сейчас в теме
(73) В документации по DateDiff-РазностьДат указывается, что сия функция считает количество границ между заданными единицами измерения.
Так что результат
РАЗНОСТЬДАТ(01.02, 01.03, МЕСЯЦ) = 1 из (59)

РАЗНОСТЬДАТ(29.02, 01.03, МЕСЯЦ) = 1 из (60)
полностью соответствует описанию функции. Хотя и не соответствует ожиданиям тех, кто ею пользуется не читая доку.
70. kasper076 49 11.02.20 10:33 Сейчас в теме
(66) А какой ответ выдает ваш запрос при следующих датах:
дата рождения = 31.03.2000
дата текущая = 01.05.2000 (эта дата не участвует в расчетах)
71. Vlad_2008 13 11.02.20 13:42 Сейчас в теме
(70)

30/04 - исполнился месяц + прошло само 30-ое апреля

Ответ = 1 месяц 1 день
72. kasper076 49 11.02.20 14:19 Сейчас в теме
(71) А сколько дней в этом месяце?
74. Vlad_2008 13 11.02.20 14:21 Сейчас в теме
75. Vlad_2008 13 11.02.20 14:24 Сейчас в теме
(72) Ну Вы можете проверить это кодом используя функцию ДобавитьМесяц.

31.03 + 1 месяц = 30.04
77. kasper076 49 11.02.20 14:34 Сейчас в теме
(75) Именно это и сделал.
ДобавитьКДате(30.03, Месяц, 1) = 30.04.
ДобавитьКДате(31.03, Месяц, 1) = 30.04
Результат странный, добавили один день, но результат не изменился.
79. Vlad_2008 13 13.02.20 17:43 Сейчас в теме
(77) Все правильно, в днях прошло разное время, а вот в месяцах - одинаковое. Т.к. количество дней в месяцах может быть разное: 28,29,30,31, то "месячный" день рождения будет "прыгать"
81. kasper076 49 13.02.20 21:18 Сейчас в теме
(79)В каких днях? Прибавляем месяц к разным датам. Не вижу смысла дальше обсуждать.
83. kasper076 49 14.02.20 10:12 Сейчас в теме
(79)
Т.к. количество дней в месяцах может быть разное

И в каком из месяцев изменилось количество дней?
85. Vlad_2008 13 14.02.20 14:33 Сейчас в теме
(83) в Апреле по сравнению с Мартом:

31 -> 30

Чет мне тоже кажется что дальше нет смысла ...
87. kasper076 49 14.02.20 14:52 Сейчас в теме
(85) в (77) я в беру две даты в марте, прибавляю у ним месяц и получаю одну и ту же дату в апреле.
76. kasper076 49 11.02.20 14:26 Сейчас в теме
(71) Тогда по чему месяц исполнится 30-го? Т.е. в апреле прошло 29 полных дней и один полный день прошёл в марте. Итого 30 дней.
80. Vlad_2008 13 13.02.20 17:49 Сейчас в теме
(76) Ну нам тут не важно сколько дней, важно узнать когда исполнился полный месяц

ДР = 31.03

Мес ДР = 30.04, т.к. в апреле нет 31-го, сл- переносим на 30-ое

На 01.05

- прошло 31.03
- прошло 29 дней апреля (до 30.04)
---------------------------------
Итого полный месяц (фактически 30 дней)

- прошло 30.04

Ответ: 1 месяц 1 день
82. kasper076 49 14.02.20 10:09 Сейчас в теме
(80)
сл- переносим на 30-ое
это какое-то общепринятое правило? Или эт вы сами для ся так решили?
84. Vlad_2008 13 14.02.20 14:26 Сейчас в теме
(82) Нет, не я. Так считают все и в функциях 1С это учтено, Вы же сами проверяли:

ДобавитьКДате(31.03, Месяц, 1) = 30.04


и скажите, какого числа в 2019 году был день рождения у человека родившегося 29.02.2000 ?

Если у Вас получится 28.02.2019, пожалуйста, не считайте что это я так придумал )))))).

И вот это тоже не я:

ДобавитьКДате(31.01.2019, Месяц, 1) = 28.02.2019
86. kasper076 49 14.02.20 14:51 Сейчас в теме
(84) Ну т.е. это не я, это программа так посчитала.
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Программист 1С
Екатеринбург
зарплата от 90 000 руб. до 150 000 руб.
Полный день

Архитектор 1С
Нижний Новгород
зарплата от 180 000 руб.
Полный день

Программист 1С
Балашиха
зарплата от 80 000 руб.
Полный день

Программист 1С
Челябинск
зарплата от 100 000 руб.
Полный день

Разработчик 1С
Нижний Новгород
зарплата до 90 000 руб.
Полный день