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

27.04.17

Разработка - Запросы

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

Как известно, в 1С есть неплохие средства работы с датами, которые в данной задаче я и попытался использовать.

И, конечно же, обработка "Консоль запросов":

Очень помогли мне функции

РАЗНОСТЬДАТ()

и 

ДОБАВИТЬКДАТЕ()

В итоге получил такие запросы, в которых выставил ограничения по количеству записей (500) для отладки информации:

ВЫБРАТЬ ПЕРВЫЕ 500
	Люди.Ссылка КАК Ссылка,
	Люди.ДатаРождения КАК ДатаРождения,
	ВЫБОР
		КОГДА МЕСЯЦ(&ТекущаяДата) < МЕСЯЦ(Люди.ДатаРождения)
			ТОГДА РАЗНОСТЬДАТ(Люди.ДатаРождения, &ТекущаяДата, ГОД) - 1
		КОГДА МЕСЯЦ(&ТекущаяДата) > МЕСЯЦ(Люди.ДатаРождения)
			ТОГДА РАЗНОСТЬДАТ(Люди.ДатаРождения, &ТекущаяДата, ГОД)
		КОГДА МЕСЯЦ(&ТекущаяДата) = МЕСЯЦ(Люди.ДатаРождения)
			ТОГДА ВЫБОР
					КОГДА ДЕНЬ(&ТекущаяДата) < ДЕНЬ(Люди.ДатаРождения)
						ТОГДА РАЗНОСТЬДАТ(Люди.ДатаРождения, &ТекущаяДата, ГОД) - 1
					КОГДА ДЕНЬ(&ТекущаяДата) >= ДЕНЬ(Люди.ДатаРождения)
						ТОГДА РАЗНОСТЬДАТ(Люди.ДатаРождения, &ТекущаяДата, ГОД)
				КОНЕЦ
		ИНАЧЕ "Смотреть"
	КОНЕЦ КАК Количество_лет
ПОМЕСТИТЬ Года
ИЗ
	Справочник.Люди КАК Люди
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПЕРВЫЕ 500
	Люди.Ссылка КАК Ссылка,
	Люди.ДатаРождения КАК ДатаРождения,
	ГОДА.Количество_лет КАК Количество_лет,
	ВЫБОР
		КОГДА МЕСЯЦ(&ТекущаяДата) < МЕСЯЦ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
			ТОГДА ВЫБОР
					КОГДА ДЕНЬ(&ТекущаяДата) >= ДЕНЬ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
						ТОГДА 
						РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)), &ТекущаяДата, МЕСЯЦ)
					КОГДА ДЕНЬ(&ТекущаяДата) < ДЕНЬ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
						ТОГДА РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)), &ТекущаяДата, МЕСЯЦ) - 1
					ИНАЧЕ
						РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)), &ТекущаяДата, МЕСЯЦ) - 1
				КОНЕЦ
		КОГДА МЕСЯЦ(&ТекущаяДата) > МЕСЯЦ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
			ТОГДА 
				ВЫБОР
					КОГДА ДЕНЬ(&ТекущаяДата) >= ДЕНЬ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
						ТОГДА 
						РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)), &ТекущаяДата, МЕСЯЦ)
					КОГДА ДЕНЬ(&ТекущаяДата) < ДЕНЬ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
						ТОГДА РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)), &ТекущаяДата, МЕСЯЦ) - 1
					ИНАЧЕ
						РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)), &ТекущаяДата, МЕСЯЦ) - 1
				КОНЕЦ
		КОГДА МЕСЯЦ(&ТекущаяДата) = МЕСЯЦ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
			ТОГДА ВЫБОР
					КОГДА ДЕНЬ(&ТекущаяДата) < ДЕНЬ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
						ТОГДА РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)), &ТекущаяДата, МЕСЯЦ) - 1
					КОГДА ДЕНЬ(&ТекущаяДата) >= ДЕНЬ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)))
						ТОГДА РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(Люди.ДатаРождения, ГОД, ВЫРАЗИТЬ(ГОДА.Количество_лет КАК ЧИСЛО)), &ТекущаяДата, МЕСЯЦ)
				КОНЕЦ
		ИНАЧЕ "Смотреть"
	КОНЕЦ КАК Количество_месяцев
Поместить ГОДАМЕСЯЦА
ИЗ
	Справочник.Люди КАК Люди
		ЛЕВОЕ СОЕДИНЕНИЕ Года КАК ГОДА
		ПО (Люди.Ссылка = ГОДА.Ссылка)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПЕРВЫЕ 500
	Люди.Ссылка КАК Ссылка,
	Люди.ДатаРождения КАК ДатаРождения,
	ГОДАМЕСЯЦА.Количество_лет,
	ГОДАМЕСЯЦА.Количество_месяцев,
	РАЗНОСТЬДАТ(ДОБАВИТЬКДАТЕ(
							ДОБАВИТЬКДАТЕ(
										Люди.ДатаРождения,
										ГОД,
										ВЫРАЗИТЬ(ГОДАМЕСЯЦА.Количество_лет КАК ЧИСЛО)
										),
							МЕСЯЦ,
							ВЫРАЗИТЬ(ГОДАМЕСЯЦА.Количество_месяцев КАК ЧИСЛО)),
				&ТекущаяДата,
				ДЕНЬ
				) КАК Количество_дней
ИЗ
	Справочник.Люди КАК Люди
		ЛЕВОЕ СОЕДИНЕНИЕ ГОДАМЕСЯЦА КАК ГОДАМЕСЯЦА
		ПО (Люди.Ссылка = ГОДАМЕСЯЦА.Ссылка)
;

Хотелось бы, конечно, довести эти запросы до совершенства, но ограничен во времени.

PS.

Не знаю, что делать с такими днями рождения - 29.02.1988. Возраст получаю - 29 лет 1 месяц 30 дней.

Если есть предложения, пишите в комментариях).

Запрос возраст количество лет месяцев дней

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    124627    681    389    

732

Пропорциональное распределение в запросе с использованием АвтоНомерЗаписи()

Запросы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    2078    andrey_sag    9    

27

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    5973    KawaNoNeko    23    

25

Набор-объект для СКД по тексту или запросу

Запросы СКД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2139    2    Yashazz    0    

30

Запрос 1С copilot

Инструментарий разработчика Запросы Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

5 стартмани

15.01.2024    6601    31    mkalimulin    27    

51

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    1874    vandalsvq    7    

29

Объектная модель запроса "Схема запроса" 2

Запросы Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

Далеко уже не новый тип данных "Схема запроса". Статья о том, как использовать его "попроще". Примеры создания текста запроса с нуля и изменение имеющегося запроса.

06.12.2023    5600    user1923546    26    

46

Начните уже использовать хранилище запросов

HighLoad оптимизация Запросы

Очень немногие из тех, кто занимается поддержкой MS SQL, работают с хранилищем запросов. А ведь хранилище запросов – это очень удобный, мощный и, главное, бесплатный инструмент, позволяющий быстро найти и локализовать проблему производительности и потребления ресурсов запросами. В статье расскажем о том, как использовать хранилище запросов в MS SQL и какие плюсы и минусы у него есть.

11.10.2023    16555    skovpin_sa    14    

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

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	РАЗНОСТЬДАТ(Данные.ДР, Данные.ТД, ГОД) + ВЫБОР
		КОГДА МЕСЯЦ(Данные.ДР) < МЕСЯЦ(Данные.ТД)
				ИЛИ МЕСЯЦ(Данные.ДР) = МЕСЯЦ(Данные.ТД)
					И ДЕНЬ(Данные.ДР) <= ДЕНЬ(Данные.ТД)
			ТОГДА 0
		ИНАЧЕ -1
	КОНЕЦ КАК Лет,
	МЕСЯЦ(Данные.ТД) - МЕСЯЦ(Данные.ДР) + ВЫБОР
		КОГДА МЕСЯЦ(Данные.ТД) - МЕСЯЦ(Данные.ДР) < 0
			ТОГДА 12
		ИНАЧЕ 0
	КОНЕЦ КАК Месяц,
	ВЫБОР
		КОГДА ДЕНЬ(Данные.ТД) - ДЕНЬ(Данные.ДР) >= 0
			ТОГДА ДЕНЬ(Данные.ТД) - ДЕНЬ(Данные.ДР)
		ИНАЧЕ ДЕНЬ(Данные.ТД) - ДЕНЬ(Данные.ДР) + РАЗНОСТЬДАТ(Данные.ТД, ДОБАВИТЬКДАТЕ(Данные.ТД, МЕСЯЦ, 1), ДЕНЬ)
	КОНЕЦ КАК День,
	Данные.ДР
ИЗ
	данные КАК Данные
Показать
user705522_constantin_h; maksa2005; autokono; +3
2. D.Gal 9 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 16 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 36 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 16 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 36 03.05.17 19:15 Сейчас в теме
(15) Високосный нужен только для 29.02, остальные дни считаются одинаково.
Логика расчета проста: каждое число следующего месяца, совпадающее с днем рождения дает полный месяц. Каждый следующий день, если месяц неполный, добавляется к дням. Именно так у вас "потерялся" один день. Полный месяц приходится на 29-е число. Затем идут 30,1,2,3. Итого 4 дня.
+
17. Vlad_2008 16 03.05.17 21:33 Сейчас в теме
(16) Да, Вы правы. Я зачем-то считал календарные месяцы, вместо реальных.

Переделал запрос, теперь все четко:
+
42. Vlad_2008 16 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 36 10.12.19 10:52 Сейчас в теме
(42) Не найду эту обработку. Чисто теоретически (по моим алгоритмам) должно быть 11 лет и 1 день.
+
44. Vlad_2008 16 10.12.19 16:39 Сейчас в теме
(43) Ой, не к тому сообщению написал ... это я к сообщению № 40

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


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

Мой мозг не смог впитать сие ...
+
25. comptr 31 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 16 04.05.17 16:45 Сейчас в теме
(25) , (27)

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


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

        ИНАЧЕ 0
    КОНЕЦ
+
4. D.Gal 9 29.04.17 13:20 Сейчас в теме
Да, невозможно, это я ошибся, только проблема с високосными годами осталась. Дни неправильно считает...
+
5. МимохожийОднако 141 03.05.17 07:42 Сейчас в теме
Полагаю в ЗУП уже есть подобные процедуры и функции
+
14. D.Gal 9 03.05.17 18:04 Сейчас в теме
(5) Можете скинуть реализацию из ЗУП?
+
19. МимохожийОднако 141 04.05.17 07:36 Сейчас в теме
(14) В ЗУП не нашёл. Может быть это?
http://kb.mista.ru/article.php?id=664
+
6. Vlan 36 03.05.17 09:37 Сейчас в теме
А почему именно запросом получать дни?
Ведь гораздо проще соорудить такую, например, конструкцию:
	Лет = 0;
	Месяцев = 0;
	Дней = 0;
	ДатаР = Объект.ДатаРождения;
	Пока ДатаР <= ТекущаяДата() Цикл
		ДатаР = ДобавитьМесяц(ДатаР,1);
		Месяцев = Месяцев + 1;
	КонецЦикла;
	Месяцев = Месяцев-1;
	Лет = Цел(Месяцев/12);
	Месяцев = Месяцев-Лет*12;
	Дней = Цел((ТекущаяДата() - ДобавитьМесяц(ДатаР,-1))/(60*60*24));
	Объект.КоличествоДней = "Лет: "+Строка(Лет)+" Месяцев: "+Строка(Месяцев)+" Дней: "+Строка(Дней);
Показать
+
13. D.Gal 9 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 36 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 16 04.05.17 14:56 Сейчас в теме
(20) Вчера гонял Ваш предыдущий вариант на ошибки и видел что на 28 числе они были, сейчас проверим новый вариант )).

Думаю, что и в Вашем варианте и в варианте из (22) будут ошибки, а думаю так, потому что Вы используете деление на "сутки". Чисто математически, очевидно, что при расчете за 1000 лет "что-то пойдет не так".
+
26. Vlan 36 04.05.17 15:44 Сейчас в теме
(23)Сомневаюсь, что за 1000 лет что-то поменяется. Если только календарь вдруг закончится, как у Майя. :-)
В моем алгоритме загвоздка была только в добавлении месяца с 29.01 до 29.02. 1C автоматом исправляла недопустимую дату на 28.02, если год не високосный. Достаточно было это обойти, чтобы программа заблистала во всей красе.
+
29. Vlad_2008 16 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 16 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 36 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 16 09.05.17 17:51 Сейчас в теме
(31) Я, думаю, что это 9 полных месяцев, т.к. "месячный" день рождения приходится именно на 28.02.2017.
+
21. Vlan 36 04.05.17 08:53 Сейчас в теме
А можно еще упростить, ведь сбивается общий расчет только для 29.02 при переходе с високосного года на обычный:
	Лет = 0; Месяцев = 0; Дней = 0;
	Сутки = 60*60*24;
	ДатаР = Объект.ДатаРождения;
    Пока ДатаР <= Объект.ЛюбаяДата Цикл
        ДатаР = ДобавитьМесяц(ДатаР,1);
		Если Месяц(ДатаР) = 3 И Не День(ДатаР) = День(Объект.ДатаРождения) Тогда
			ДатаР = ДатаР+Сутки;
		КонецЕсли;
        Месяцев = Месяцев+1;
    КонецЦикла;
    Месяцев = Месяцев-1;
    Лет = Цел(Месяцев/12);
    Месяцев = Месяцев-Лет*12;
    Дней = Цел((Объект.ЛюбаяДата-ДобавитьМесяц(ДатаР,-1))/Сутки);
    Объект.КоличествоДней = "Лет: "+Строка(Лет)+" Месяцев: "+Строка(Месяцев)+" Дней: "+Строка(Дней);
Показать
+
88. 1C_tradeomsk 105 15.12.20 15:29 Сейчас в теме
Очешуеть ... в алгоритме должно быть две даты на входе - Дата рождения и Текущая.

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

ПолныхЛет = Год(ТекДата) - Год(ДатаРождения) 
					- ?(Месяц(ТекДата) < Месяц(ДатаРождения) 
						Или Месяц(ТекДата) = Месяц(ДатаРождения) И День(ТекДата) < День(ДатаРождения), 
 						1, 0);
tsatsur; 1serger; user886825; insurgut; PORGY3000; maksa2005; Samarin; TSSV; katakuna; +9
38. D.Gal 9 07.04.19 21:45 Сейчас в теме
(37) Вы когда этот комментарий писали, думали хоть, что в контексте моего запроса и задачи он вообще ничего значит. Зачем мне количество полных лет кодом, когда я написал, что задачу необходимо решать запросом было? Или Вы может не мне написали?
+
39. [4EPHbIYY_KOT] 39 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 16 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 191 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 16 12.12.19 12:00 Сейчас в теме
Что-то, за два года, мы так и не увидели "правильный" запрос по расчету возраста в Год-Месяц-День ... будем ждать дальше ))

Да, онлайн калькуляторы тоже смотрел, ржал, почти все показывают какую-то ерунду.
+
51. sssss_aaaaa_2011 04.02.20 21:14 Сейчас в теме
(49)
Давно не заглядывал на инфостарт, а тут такое...
Одни все изобретают вечный двигатель, а прогеры пишут расчет разницы дат в годах, месяцах и днях...
До сих пор никто из тусующихся тут, похоже, еще не знает, что НЕТ одного алгоритма расчета разницы дат ибо нет одной размерности у таких единиц измерения как год и месяц. Вы в каких годах и месяцах собрались все это мерить? В средних, максимальных, минимальных, фиксированных, учетных, условных?
Есть несколько специальных алгоритмов для конкретных случаев (стажи, возрасты, сроки и т.д.), но все они считают по-разному. И правила их расчета уже давно придуманы, и устанавливаются не прогерами, а соответствующими правилами и инструкциями. И даже один, вроде бы, период, например, с 01.01 по 29.03, при расчете по одному алгоритму может давать разные результаты в разные годы.
+
52. Vlad_2008 16 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 103 07.02.20 17:07 Сейчас в теме
(53) Мой запрос именно по календарю и считает.
+
56. sssss_aaaaa_2011 07.02.20 17:54 Сейчас в теме
(55)Кто вам сказал такую чушь? Арифметические операции с частями даты вдруг стали привязаны к календарю? И перестали быть частью некоей формулы?
+
57. kasper076 103 07.02.20 19:20 Сейчас в теме
(56) По вашему день(конецпериода(Дата, месяц)) это арифметическая операция?
+
60. sssss_aaaaa_2011 10.02.20 09:34 Сейчас в теме
(57)Это получение некоего числа, которое к конкретной дате уже не имеет никакого отношения. Как и все дальнейшие операции с ним.
+
63. kasper076 103 10.02.20 14:08 Сейчас в теме
(60)
Это получение некоего числа, которое к конкретной дате уже не имеет никакого отношения. Как и все дальнейшие операции с ним.

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

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

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

Вот немного для понимания сути вопроса:
Как получить разницу двух дат в формате: лет, месяцев, дней
+
54. kasper076 103 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 16 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 103 10.02.20 11:53 Сейчас в теме
(58)
Используя ДатаТекущая мой запрос получается проще и ни каких проблем
неоднократно ссылаетесь на некий ваш запрос, но в теме я его текст не нашел. Можете его тут показать?
+
50. kasper076 103 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 16 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 103 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 16 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 103 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 16 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 103 11.02.20 07:53 Сейчас в теме
(66) Так оба же не верные. На работу приеду проверю.
+
69. sssss_aaaaa_2011 11.02.20 09:24 Сейчас в теме
(66)
хочется увидеть запрос который считает без ошибок ))

Господа, вас не наводит ни на какие мысли тот факт, что календарями и датами человечество пользуется уже не одну тысячу лет, но до сих пор тоже человечество не придумало того самого способа получения дат в формате лет, месяцев, дней, который вы тут пытаетесь создать? Или вы такой уже видели и сейчас решили заняться изобретением велосипеда? Вам не кажется, что ситуация очень сильно напоминает ситуацию с вечным двигателем? Все не против бы его увидеть, некоторые даже пытались/пытаются его сделать, как всегда чего-то вот совсем чуть-чуть доработать, почти работает, но воз и ныне там.
+
73. Vlad_2008 16 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)
полностью соответствует описанию функции. Хотя и не соответствует ожиданиям тех, кто ею пользуется не читая доку.
+
93. Zurfik 04.06.21 06:46 Сейчас в теме
(78)
Изобретение велосипеда продолжается, но мне очень понравилось ваше объяснение почему решить эту задачу в запросе не представляется возможным.
+
70. kasper076 103 11.02.20 10:33 Сейчас в теме
(66) А какой ответ выдает ваш запрос при следующих датах:
дата рождения = 31.03.2000
дата текущая = 01.05.2000 (эта дата не участвует в расчетах)
+
71. Vlad_2008 16 11.02.20 13:42 Сейчас в теме
(70)

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

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

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

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

31 -> 30

Чет мне тоже кажется что дальше нет смысла ...
+
87. kasper076 103 14.02.20 14:52 Сейчас в теме
(85) в (77) я в беру две даты в марте, прибавляю у ним месяц и получаю одну и ту же дату в апреле.
+
76. kasper076 103 11.02.20 14:26 Сейчас в теме
(71) Тогда по чему месяц исполнится 30-го? Т.е. в апреле прошло 29 полных дней и один полный день прошёл в марте. Итого 30 дней.
+
80. Vlad_2008 16 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 103 14.02.20 10:09 Сейчас в теме
(80)
сл- переносим на 30-ое
это какое-то общепринятое правило? Или эт вы сами для ся так решили?
+
84. Vlad_2008 16 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 103 14.02.20 14:51 Сейчас в теме
(84) Ну т.е. это не я, это программа так посчитала.
+
89. Cvetic 307 16.03.21 14:07 Сейчас в теме
Можно сделать так:
Возраст = Год(Дата(01, 01, 01) + (ТекущаяДата() - ДатаРождения)) - 1
+
92. Vlad_2008 16 19.03.21 12:21 Сейчас в теме
(89)
Возраст = Год(Дата(01, 01, 01) + (ТекущаяДата() - ДатаРождения)) - 1


И это тоже не будет работать, т.к. будут искажения на високосных годах, что учесть в разнице дней не возможно, да еще прибавляя ее к нулевой дате.
+
90. Cvetic 307 16.03.21 14:09 Сейчас в теме
Если запросом то:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РАЗНОСТЬДАТ(&ДатаРождения, &ТекущаяДата, ГОД) КАК Возраст";

Запрос.УстановитьПараметр("ДатаРождения" , ДатаРождения);
Запрос.УстановитьПараметр("ТекущаяДата" , ТекущаяДата());
+
91. Vlad_2008 16 19.03.21 12:10 Сейчас в теме
(90)
РАЗНОСТЬДАТ(&ДатаРождения, &ТекущаяДата, ГОД)


Конечно так не получится, сравните:

Дата рожд / Дата тек / Возраст


01.03.2020 19.03.2021 1
19.03.2020 19.03.2021 1
20.03.2020 19.03.2021 1

Причем, Вы пытаетесь получить только ГОДЫ, а в задаче еще требуются месяцы и дни ...
+
94. Vlad_2008 16 14.06.21 05:14 Сейчас в теме
Да, три года прошли, но как-то бледно. Что-то надо делать ...

В своих расчетах делаю так:

1) ГОДЫ - разность лет между Датой Рождения и Последним днем рождения
2) МЕСЯЦЫ - разность месяцев между Последним днем рождения и Последним "месячным" днем рождения
3) ДНИ - ... Посл "месячный" и сейчас (или дата на которую считаем)

Три строчки ...

Пусть ДР = 01.05.2001, считаем на 14.06.2021 (эту дату не включаем)

1) разность 01.05.2001 и 01.05.2021 в годах = 20 лет
2) разность 01.05.2021 и 01.06.2021 в месяцах = 1 месяц
3) разность 01.06.2021 и 14.06.2021 в днях = 13 дней

... хоть кодом, хоть запросом, сделать проблем не вижу.
birusik; +1
Внимание! Тема сдана в архив