![]() |
|
Ближайшая дата рождения (задачка на программирование) | ☑ | ||
---|---|---|---|---|
0
дущ
16.12.16
✎
01:28
|
Встала задача определить ближайшее день рождения у произвольного человека. Ближайшее не только будущее, но и прошедшее. То есть, определить что ближе: прошлое или будущее день рождения.
Написал вот такой вот ужас ДеньРожденияВЭтомГоду = ДобавитьМесяц(НачалоГода(Дата), Месяц(рКарта.ДеньРождения) - 1) + (День(рКарта.ДеньРождения) - 1) * 86400; ДеньРожденияВПрошломГоду= ДобавитьМесяц(НачалоГода(ДобавитьМесяц(Дата, - 12)), Месяц(рКарта.ДеньРождения) - 1) + (День(рКарта.ДеньРождения) - 1) * 86400; ДеньРожденияВСледующемГоду= ДобавитьМесяц(НачалоГода(ДобавитьМесяц(Дата, + 12)), Месяц(рКарта.ДеньРождения) - 1) + (День(рКарта.ДеньРождения) - 1) * 86400; РазницаВЭтомГоду = (Дата - ДеньРожденияВЭтомГоду); РазницаВЭтомГоду = Макс(РазницаВЭтомГоду, - РазницаВЭтомГоду); РазницаВПрошломГоду = (Дата - ДеньРожденияВПрошломГоду); РазницаВПрошломГоду = Макс(РазницаВПрошломГоду, - РазницаВПрошломГоду); РазницаВСледующемГоду = (Дата - ДеньРожденияВСледующемГоду); РазницаВСледующемГоду = Макс(РазницаВСледующемГоду, - РазницаВСледующемГоду); Если РазницаВЭтомГоду > РазницаВПрошломГоду Тогда Если РазницаВПрошломГоду > РазницаВСледующемГоду Тогда ДеньРождения = ДеньРожденияВСледующемГоду; Иначе ДеньРождения = ДеньРожденияВПрошломГоду; КонецЕсли; Иначе Если РазницаВЭтомГоду > РазницаВСледующемГоду Тогда ДеньРождения = ДеньРожденияВСледующемГоду; Иначе ДеньРождения = ДеньРожденияВЭтомГоду; КонецЕсли; КонецЕсли; где Дата - текущая дата, а рКарта.ДеньРождения - дата, когда родился клиент. Вкратце, нахожу три даты ближайшие дни рождения человека (например, родился 13.03.1980, я нахожу 13.03.2015, 13.03.2016 и 13.03.2017, среди них точно будет ближайшее день рождения), и ищу минимальную разницу между этими датами и сегодняшним днем. Получается очень сложно, долго, длинно, непонятно. Печенкой чую, есть изящнее решение. Может кто-то найдет и приведёт? |
|||
1
Torquader
16.12.16
✎
01:36
|
Расстояние между двумя датами - это от большей отнять меньшую - после того как будет таблица, можно по ней взять минимум.
И что тут сложного ? |
|||
2
Torquader
16.12.16
✎
01:37
|
Проблема только с теми, кто родился 29 февраля - не очень понятно, что считать меньшей, а что большей датой дня рождения.
|
|||
3
дущ
16.12.16
✎
01:46
|
Задача в том, что бы найти это как можно проще.
|
|||
4
Zhuravlik
16.12.16
✎
01:48
|
(0) ДатаРождения = Дата(1980, 3, 21);
ДеньДаты = День(ДатаРождения); МесяцДаты = Месяц(ДатаРождения); ТекДата = НачалоДня(ТекущаяДата()); НомерТекущегоГода = Год(ТекущаяДата()); ДатаРожденияВТекущемГоду = Дата(НомерТекущегоГода, МесяцДаты, ДеньДаты); ДатаРожденияВПрошломГоду = Дата(НомерТекущегоГода - 1, МесяцДаты, ДеньДаты); ДатаРожденияВБудущемГоду = Дата(НомерТекущегоГода + 1, МесяцДаты, ДеньДаты); СоответствиеИнтервалДата = Новый Соответствие; инт_Прошлый = ДатаРожденияВПрошломГоду - ТекДата; СоответствиеИнтервалДата.Вставить(инт_Прошлый, ДатаРожденияВПрошломГоду); инт_Прошлый = Макс(инт_Прошлый, -инт_Прошлый); инт_Текущий = ДатаРожденияВТекущемГоду - ТекДата; СоответствиеИнтервалДата.Вставить(инт_Текущий, ДатаРожденияВТекущемГоду); инт_Текущий = Макс(инт_Текущий, -инт_Текущий); инт_Будущий = ДатаРожденияВБудущемГоду - ТекДата; СоответствиеИнтервалДата.Вставить(инт_Будущий, ДатаРожденияВБудущемГоду); инт_Будущий = Макс(инт_Будущий, -инт_Будущий); НаименьшийИнтервал = Мин(инт_Прошлый, инт_Текущий, инт_Будущий); ДатаРожденияБлижайшая = СоответствиеИнтервалДата.Получить(НаименьшийИнтервал); Если ДатаРожденияБлижайшая = Неопределено Тогда ДатаРожденияБлижайшая = СоответствиеИнтервалДата.Получить(-НаименьшийИнтервал); КонецЕсли; Осталось понять что с (2) делать) |
|||
5
Torquader
16.12.16
✎
02:13
|
На самом деле, у нас есть таблица: ИдЧеловека,ДеньРождения,МесяцРождения
лтзДниРождения - таблица значений Функция мфПолучитьБлижайшийДеньРождения(птзДниРожденияСотрудников) лтзБлижайшиеДаты=Новый ТаблицаЗначений; лтзБлижайшиеДаты.Колонки.Добавить("Человек"); лтзБлижайшиеДаты.Колонки.Добавить("ДеньРождения"); лтзБлижайшиеДаты.Колонки.Добавить("Разница"); лчТекущаяДата=НачалоДня(ТекущаяДата()); лчТекущийГод=ДатаГод(лчТекущаяДата); Для Каждого лстзДеньРождения Из птзДниРожденияСотрудников Цикл лчДень=лстзДеньРождения.ДеньРождения; лчМесяц=лстзДеньРождения.МесяцРождения; Если(лчДень=29)И(лчМесяц=2)Тогда лстзБлижайшаяДата=лтзБлижайшиеДаты.Добавить(); лстзБлижайшаяДата.Человек=лстзДеньРождения.ИдЧеловека; лстзБлижайшаяДата.ДеньРождения=Дата(лчТекущийГод-1,2,28,0,0,0)+86400; лстзБлижайшаяДата.Разница=лчТекущаяДата-лстзБлижайшаяДата.ДеньРождения; лстзБлижайшаяДата=лтзБлижайшиеДаты.Добавить(); лстзБлижайшаяДата.Человек=лстзДеньРождения.ИдЧеловека; лстзБлижайшаяДата.ДеньРождения=Дата(лчТекущийГод,2,28,0,0,0)+86400; лчРазница=лчТекущаяДата-лстзБлижайшаяДата.ДеньРождения; Если лчРазница<0 Тогда лстзБлижайшаяДата.Разница=-лчРазница; Иначе лстзБлижайшаяДата.Разница=лчРазница; КонецЕсли; лстзБлижайшаяДата=лтзБлижайшиеДаты.Добавить(); лстзБлижайшаяДата.Человек=лстзДеньРождения.ИдЧеловека; лстзБлижайшаяДата.ДеньРождения=Дата(лчТекущийГод+1,2,28,0,0,0)+86400; лстзБлижайшаяДата.Разница=лстзБлижайшаяДата.ДеньРождения-лчТекущаяДата; Иначе лстзБлижайшаяДата=лтзБлижайшиеДаты.Добавить(); лстзБлижайшаяДата.Человек=лстзДеньРождения.ИдЧеловека; лстзБлижайшаяДата.ДеньРождения=Дата(лчТекущийГод-1,лчМесяц,лчДень,0,0,0); лстзБлижайшаяДата.Разница=лчТекущаяДата-лстзБлижайшаяДата.ДеньРождения; лстзБлижайшаяДата=лтзБлижайшиеДаты.Добавить(); лстзБлижайшаяДата.Человек=лстзДеньРождения.ИдЧеловека; лстзБлижайшаяДата.ДеньРождения=Дата(лчТекущийГод,лчМесяц,лчДень,0,0,0); лчРазница=лчТекущаяДата-лстзБлижайшаяДата.ДеньРождения; Если лчРазница<0 Тогда лстзБлижайшаяДата.Разница=-лчРазница; Иначе лстзБлижайшаяДата.Разница=лчРазница; КонецЕсли; лстзБлижайшаяДата=лтзБлижайшиеДаты.Добавить(); лстзБлижайшаяДата.Человек=лстзДеньРождения.ИдЧеловека; лстзБлижайшаяДата.ДеньРождения=Дата(лчТекущийГод+1,лчМесяц,лчДень,0,0,0); лстзБлижайшаяДата.Разница=лстзБлижайшаяДата.ДеньРождения-лчТекущаяДата; КонецЕсли; КонецЦикла; лтзБлижайшиеДаты.Сортировать("Разница Возр"); Если лтзБлижайшиеДаты.Количество()=0 Тогда Возврат НЕОПРЕДЕЛЕНО; КонецЕсли; лстзТекущийДеньРождения=лтзБлижайшиеДаты[0]; Возврат Новый Структура("Человек,ДеньРождения",лстзТекущийДеньРождения.Человек,лстзТекущийДеньРождения.ДеньРождения); КонецФункции |
|||
6
SeraFim
16.12.16
✎
03:20
|
1. Определяем КоличествоПолныхЛет
2. Прибавляем к дате рождения КоличествоПолныхЛет и КоличествоПолныхЛет+1. 3. ищем, какая из этих 2 дат ближе к текущей дате Плюсы подобного подхода: - Никаких проблем с 29 февраля. - Выбирать придется из 2 дат, а не 3 |
|||
7
SeraFim
16.12.16
✎
03:24
|
+ (6) предвижу вопросы - а как считать КоличествоПолныхЛет? Вот стандартный типовой способ для запроса - можно переделать в обычный код :)
|
|||
8
Mort
16.12.16
✎
07:40
|
ДатаРождения = '08.05.1982';
ТекущаяДата = ТекущаяДата(); Результат = ДатаРождения; СледующийГод = Дата(Год(Результат) + 1, Месяц(Результат), День(Результат)); Пока Макс(ТекущаяДата - Результат, Результат - ТекущаяДата) > Макс(ТекущаяДата - СледующийГод, СледующийГод - ТекущаяДата) Цикл Результат = СледующийГод; СледующийГод = Дата(Год(Результат) + 1, Месяц(Результат), День(Результат)); КонецЦикла; Сообщить(Результат); |
|||
9
xxTANATORxx
16.12.16
✎
09:31
|
(0)ИМХО одним запросом делается
есчо лень писать |
|||
10
SSSSS_AAAAA
16.12.16
✎
09:47
|
" ближайшее день "
День - он, потому "ближайшИЙ". |
|||
11
Кирпич
16.12.16
✎
10:06
|
(10) у нас на районе не звонЯт, а звОнят
|
|||
12
rabbidX
16.12.16
✎
10:16
|
Если МесяцТекущейДаты >=7 Тогда ПосчитатьИСравнитьРазницуВЭтомИБудущемГоду(...);
Иначе ПосчитатьИСравнитьРазницуВЭтомИПрошломГоду (...); КонецЕсли; |
|||
13
rabbidX
16.12.16
✎
10:20
|
Если МесяцДатыРождения >= 7 Тогда
НеСчитатьРазницуСБудущимГодом = Истина; Иначе НеСчитатьРазницуСПрошлымГодом = Истина; КонецЕсли; |
|||
14
Вафель
16.12.16
✎
10:20
|
сначала привести все даты к 0 году, потом обычная задача на минимум
|
|||
15
Азазелло
18.12.16
✎
20:28
|
(0) ДеньГода
Д1 = ДеньГода(ДатаДР); Д2 = ДеньГода(ТекущаяДата()); А ближайшее ДР будет через Макс(0, Д1 - Д2) дней |
|||
16
Азазелло
18.12.16
✎
20:29
|
+(15) будет или было, в зависимости от знака Д1 - Д2
|
|||
17
Euguln
18.12.16
✎
20:34
|
(9) + 1. РАЗНОСТЬДАТ И МИНИМУМ.
|
|||
18
Vaflya
18.12.16
✎
20:56
|
Запросом запросто
|
|||
19
Лефмихалыч
18.12.16
✎
21:01
|
(0) и правда ужас. Там тупое соединение на больше-меньше и минимум-максимум.
|
|||
20
Vaflya
18.12.16
✎
21:22
|
(19) та ну, видится выбор когда разница между тек.дата и будущий др больше разницы между тек.датой и прошедшим др.тогда прошедший
|
|||
21
Vaflya
18.12.16
✎
21:24
|
Всмысле даже соединений не нужно
|
|||
22
MetaDon
18.12.16
✎
21:25
|
да = РазницаДат()>183 дня ;
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |