У меня очень простая форма с компонентами TDateEdit
, TButton
и TLabel
.
Как лучше всего узнать возраст человека, если указанная дата является датой его рождения? Как бы кто-то сделал это в Delphi из компонента TDateEdit
, а затем отобразил бы возраст в метке?
Может быть, есть встроенная функция или что-то, что я могу использовать, чтобы получить возраст кого-то по дате его рождения в компоненте? Я ищу самый простой, легкий и лучший способ сделать это.
@IanBoyd Когда он покажет 18, когда на самом деле человеку все еще 17?
datediff
; он считает номер интервала переходы, а не разницу дат.
YearsBetween просто делит период между параметрами на 365,25 дня. Во многих крайних случаях это не сработает, когда приближается день рождения. Рассмотрим человека, которому сегодня, 28 мая 2019 г., исполнилось 18 лет, родившегося 28 мая 2001 г. YearsBetween берет возраст в днях, 6574, и делит на 365,25, чтобы получить 17,9986310746064, и возвращает 17. Ответ Яна Бойда даст правильный результат.
Вычесть один год из другого. Вычтите единицу, если дата в течение года не наступила.
Я не понимаю, какое это имеет отношение к firemonkey?
@J... TDateEdit - это компонент FireMonkey.
Вы можете использовать функцию YearsBetween() из модуля System.DateUtils, чтобы вычислить количество лет между сегодняшним днем (которое вы получаете из функции сейчас) и датой в вашем компоненте TDateEdit
, которую вы получаете из свойства даты.
Label1.Text:= Trunc(YearsBetween(Now,DateEdit1.Date)).toString;
Вы не можете использовать YearsBetween для вычисления возраста человека. Пожалуйста, смотрите мой комментарий выше.
Вот функция для вычисления чьего-то возраста.
Она заметно отличается от функции RTL ГодыМежду, поскольку вычисляет количество лет между двумя датами; и принципиально не совпадает с чьим-то возрастом.
function GetAge(const BirthDate, CurrentDate: TDateTime): Integer;
var
y1, m1, d1: Word; //born
y2, m2, d2: Word; //today
begin
Result := 0;
if CurrentDate < BirthDate then
Exit;
DecodeDate(BirthDate, y1, m1, d1);
DecodeDate(CurrentDate, y2, m2, d2);
//Fudge someone born on the leap-day to Feb 28th of the same year
//strictly for the purposes of this calculation
if ( (m1=2) and (d1=29) )
and
( not IsLeapYear(y2) ) then
begin
d1 := 28;
end;
Result := y2-y1; //rough count of years
//Take away a year of the month/day is before their birth month/day
if (m2 < m1) or
((m2=m1) and (d2<d1)) then
Dec(Result);
end;
Это вовсе не кажется самым простым и легким способом.
@kobik Может быть, это только код, но есть комментарии, которые довольно четко объясняют функциональность, я бы, наверное, просто добавил, зачем использовать эту функцию вместо YearsBetween.
Я предпочитаю ответ Яна Бойда, но для тех, кто настаивает на том, что YearsBetween - это правильный путь, вот альтернатива.
Если Y является результатом YearsBetween, то правильным результатом будет либо Y, либо Y+1. Эта подпрограмма вызывает YearsBetween и возвращает Y+1. Затем он использует IncYear, чтобы проверить, не слишком ли велик ответ. Если это так, он возвращает Y.
Это может показаться проще, но за кулисами происходит гораздо больше работы. Ответ Яна Бойда - это тот, который вы должны использовать.
function AgeInCompleteYears ( const nBirthDate : tDateTime;
const nCurrentDate : tDateTime ) : integer;
begin
Result := 1 + DateUtils.YearsBetween ( nCurrentDate, nBirthDate );
if DateUtils.IncYear ( nBirthDate, Result ) > nCurrentDate then
dec ( Result );
end;
function GetAge(BirthDate:TDateTime; RefDate:TDateTime=0):Integer;
begin
if RefDate=0 then RefDate:= Today;
Result := Trunc((RefDate- BirthDate) / 365.25)
end;
Каково предназначение ".25"?
@MartynA Я предполагаю, что это связано с високосным днем (29 февраля), который существует только каждые 4 года.
Привет @MarcGuillot. Да, я думал, что это может быть что-то в этом роде, но это, кажется, упускает из виду тот факт, что не каждый четвертый год является високосным. В любом случае, давайте послушаем, что скажет ОП.
Будьте осторожны, используя функцию ГодыМежду, так как она может сказать, что кому-то 18 лет, хотя на самом деле ему все еще 17.