Во-первых, обратите внимание на предположение, что если, например, вы родились 1 февраля, то следующего 1 марта вам будет ровно 1 месяц, даже если ваш возраст в днях составляет всего 28 дней - меньше, чем продолжительность среднего месяца. . Годы также имеют переменную длину (из-за високосных лет), что означает, что ваш возраст в день вашего рождения обычно не является точным целым числом лет. Если вы хотите выразить точное количество времени, которое вы прожили в годах / месяцах / днях, посмотрите мой другой ответ. Но, скорее всего, вы захотите обмануть это как раз так, чтобы рождение 1 февраля означало, что каждое 1 февраля вам будет X лет, 0 месяцев и 0 дней, а 1-го числа любого месяца вам будет X лет, Y месяцев, и 0 дней.
В таком случае читайте дальше. (NB: следующее работает только для дат в прошлом.)
Учитывая дату рождения (y,m,d)
, текущую дату (ynow,mnow,dnow)
и функцию tm()
, которая дает время unix / epoch для для заданной даты следующее выведет список из трех элементов с указанием возраста в виде {лет, месяцев, дней}:
t0 = y*12 + m - 1; # total months for birthdate.
t = ynow*12 + mnow - 1; # total months for Now.
dm = t - t0; # delta months.
if(dnow >= d) return [floor(dm/12), mod(dm,12), dnow-d];
dm--; t--;
return [floor(dm/12), mod(dm,12),
(tm({ynow,mnow,dnow}) - tm({floor(t/12), mod(t,12)+1, d}))/60/60/24];
Ниже приведен эквивалентный алгоритм, если вам не нравятся все этажи и моды. Но я думаю, что вышесказанное лучше. Во-первых, он избегает вызова tm()
, когда в этом нет необходимости.
{yl, ml} = {ynow, mnow};
if(mnow < m || mnow == m && dnow < d) yl--;
if(dnow < d) ml--;
years = yl - y;
months = ml + 12*(ynow - yl) - m;
yl = ynow;
if(ml == 0) { ml = 12; yl--; }
days = (tm({ynow, mnow, dnow}) - tm({yl, ml, d}))/60/60/24;
return [years, months, days];
person
dreeves
schedule
18.01.2009