Как я могу вычислить возраст человека в году, месяце, днях?

Также можно использовать этот синтаксис для данных из области public_profile (проверен в Graph API v2.9):

FB.api('/me?fields=birthday,link,gender,age_range', function(response) {
   console.log(response);
});

Вы можете проверить возможные значения онлайн в Graph API Explorer, просто нажмите кнопку «Получить токен»:

https://developers.facebook.com/tools/explorer/?method=GET&path=me%3Ffields%3Dbirthday%2Clink%2Cgender%2Cage_range& ; версия = v2.9

19
задан Baishampayan Ghose 19 January 2009 в 05:02
поделиться

7 ответов

Во-первых, отметьте предположение, что, если, например, Вы родились 1-го февраля затем на следующем 1-го марта, Вам точно 1 месяц, даже при том, что Ваш возраст в днях - только 28 - меньше, чем продолжительность среднего месяца. Годы также имеют переменную длину (из-за високосных годов), что означает, что Ваш возраст в Ваш день рождения обычно является не точным целым числом лет. Если Вы хотите выразить точное количество времени, Вы были живы в годах/месяцах/днях, см. мой другой ответ. Но более вероятно Вы хотите уклониться от него просто право так, чтобы рождение 1-го февраля означало, что каждый 1-го февраля Вы - X лет, 0 месяцев, и 0 дней, и на 1-м из любого месяца Вы - X лет, Y месяцы и 0 дней.

В этом случае, продолжает читать. (NB: следующий только работает на даты в прошлом.)

, Учитывая дату рождения, (y,m,d), текущая дата, (ynow,mnow,dnow), и функция tm(), который дает время Unix/эпохи для данной даты , следующее произведет список с 3 элементами, дающий возраст как {годы, месяцы, дни}:

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];
17
ответ дан 30 November 2019 в 04:37
поделиться

Это не легкий вопрос, с тех пор выше дней (если мы не принимаем во внимание секунды прыжка ) нет легких формул.

Месяцы могут состоять из 28, 29, 30, или 31 день; годы могут составить 365 или 366 дней. Поэтому проблемы возникают, когда Вы пытаетесь вычислить полные единицы времени на месяцы и годы.

Вот интересная статья , которая принимает во внимание все сложные аспекты для решения вопроса в Java.

4
ответ дан 30 November 2019 в 04:37
поделиться

Другие здесь имеют верное представление - Вы просто должны смочь расширить его до других языков. Много компьютерных систем считают время в секундах от отдельного момента ("эпоха" или "ссылочная дата") и выясняют дату оттуда, а также методы предложения для преобразования с секунд в даты. Необходимо смочь получить текущее время в секундах, преобразовать дату рождения в секунды с эпохи, вычесть два значения, затем разделить это на число секунд через день:

int timenow = time(0);
struct tm birthday = { tm_mday = 16 , .tm_mon = 1 , .tm_year = 1963 };
int timebirth = mktime( &birthday_tm );
int diff_sec = timenow - timebirth;
int days = diff_sec / ( 24 * 60 * 60);
printf("%d - %d = %d seconds, or %d days\n", timenow, timebirth, diff_sec, days);

ошибка в этом конкретном коде - то, что mktime () не может иметь дело с датами перед эпохой, которая является Jan 1 1970 в основанных на Unix системах. Подобные проблемы будут существовать в других системах в зависимости от того, как они считают время. Общий алгоритм должен работать, просто необходимо знать пределы на определенные системы.

3
ответ дан 30 November 2019 в 04:37
поделиться

С лет месяцев и даже дни могут иметь неравномерные длины, Вы не можете запустить путем вычитания этих двух дат для получения простой продолжительности. Если Вы хотите, чтобы результат совпал с тем, как люди рассматривают даты, вместо этого необходимо работать с реальными датами, использование языка создало в функциях, которые понимают даты лучше, чем Вы когда-нибудь будете.

то, Как тот алгоритм записан, зависит от языка, который Вы используете, потому что каждый язык имеет различный набор функций. Моя собственная реализация в Java, с помощью неловкого, но технически корректного GregorianCalendar:

Term difference (Date from, Date to) {
    GregorianCalendar cal1 = new GregorianCalendar();
    cal1.setTimeInMillis(from.getTime());

    GregorianCalendar cal2 = new GregorianCalendar();
    cal2.setTimeInMillis(to.getTime());

    int years = cal2.get(Calendar.YEAR) - cal1.get(Calendar.YEAR);
    int months = cal2.get(Calendar.MONTH) - cal1.get(Calendar.MONTH);
    int days = cal2.get(Calendar.DAY_OF_MONTH) - cal1.get(Calendar.DAY_OF_MONTH);
    if (days < 0) {
        months--;
        days += cal1.getActualMaximum(Calendar.DAY_OF_MONTH);
    }
    if (months < 0) {
        years--;
        months += 12;
    }
    return new Term(years, months, days);
}

Это не может быть прекрасно, но это обеспечивает человекочитаемые результаты. Термин является моим собственным классом для хранения периодов человеческого стиля, так как библиотеки даты Java не имеют того.

Для будущих проектов я планирую переместиться в намного лучшую библиотеку даты/времени Joda, которая действительно имеет класс Периода в нем и должна будет, вероятно, переписать эту функцию.

1
ответ дан 30 November 2019 в 04:37
поделиться

Вот способ сделать это, если Вы готовы нарушить принцип, "Я должен быть целым числом лет в мой день рождения". Обратите внимание, что тот принцип не строго верен, из-за високосных годов, таким образом, следующее на самом деле более точно, хотя, возможно, менее интуитивный. Если бы Вы хотите знать фактическое точное число лет, кто-то, это - способ, которым я сделал бы это.

Первое преобразование и дата рождения и текущее время ко времени эпохи (число секунд с незапамятных времен, т.е., 1970 на земле Unix) и вычитают их. Посмотрите, например, этот вопрос для того, как сделать это: , Как я преобразовываю дату/время во время эпохи (иначе время Unix - секунды с 1970) в Perl? . Вы теперь имеете точный возраст человека в секундах и должны преобразовать это в строку как "36 лет, 3 месяца, 8 дней".

Вот псевдокод, чтобы сделать это. Это должно быть просто для удаления недель или часов или безотносительно частей, которые Вы не хотите...

daysInYear = 365.2425;  # Average lengh of a year in the gregorian calendar.
                        # Another candidate for len of a year is a sidereal year,
                        # 365.2564 days.  cf. http://en.wikipedia.org/wiki/Year
weeksInYear = daysInYear / 7;
daysInMonth = daysInYear / 12;
weeksInMonth = daysInMonth / 7;
sS = 1;
mS = 60*sS;
hS = 60*mS;
dS = 24*hS;
wS = 7*dS;
oS = daysInMonth*dS;
yS = daysInYear*dS;

# Convert a number of seconds to years,months,weeks,days,hrs,mins,secs.
seconds2str[secs] 
{
  local variables:
    y, yQ= False, o, oQ= False, w, wQ= False,
    d, dQ= False, h, hQ= False, m, mQ= False, s= secs;

  if(secs<0) return "-" + seconds2str(-secs);  # "+" is string concatenation.

  y = floor(s/yS);
  if(y>0) yQ = oQ = wQ = dQ = hQ = mQ = True;
  s -= y * yS;

  o = floor(s/oS);
  if(o>0) oQ = wQ = dQ = hQ = mQ = True;
  s -= o * oS;

  w = floor(s/wS);
  if(w>0) wQ = dQ = hQ = mQ = True;
  s -= w * wS;

  d = floor(s/dS);
  if(d>0) dQ = hQ = mQ = True;
  s -= d * dS;

  h = floor(s/hS);
  if(h>0) hQ = mQ = True;
  s -= h * hS;

  m = floor(s/mS);
  if(m>0) mQ = True;
  s -= m * mS;

  return
    (yQ ? y + " year"  + maybeS(y) + " " : "") + 
    (oQ ? o + " month" + maybeS(o) + " " : "") + 
    (wQ ? w + " week"  + maybeS(w) + " " : "") + 
    (dQ ? d + " day"   + maybeS(d) + " " : "") + 
    (hQ ? dd(h) + ":" : "") + 
    (mQ ? dd(m) + ":" + dd(round(s)) + "s" : s + "s");
}


# Returns an "s" if n!=1 and "" otherwise.
maybeS(n) { return (n==1 ? "" : "s"); }

# Double-digit: takes a number from 0-99 and returns it as a 2-character string.
dd(n) { return (n<10 ? "0" + tostring(n) : tostring(n)); }
2
ответ дан 30 November 2019 в 04:37
поделиться

Так как Вы, очевидно, используете Python: Создайте к объектам даты и времени, один со "днем рождения" и один с "теперь", вычтите их и считайте возраст из получающегося объекта timedelta.

, Почему, беспокоясь вещами как високосные годы?

-4
ответ дан 30 November 2019 в 04:37
поделиться

Вот это с использованием математического правила заимствования.

        DateTime dateOfBirth = new DateTime(2000, 4, 18);
        DateTime currentDate = DateTime.Now;

        int ageInYears = 0;
        int ageInMonths = 0;
        int ageInDays = 0;

        ageInDays = currentDate.Day - dateOfBirth.Day;
        ageInMonths = currentDate.Month - dateOfBirth.Month;
        ageInYears = currentDate.Year - dateOfBirth.Year;

        if (ageInDays < 0)
        {
            ageInDays += DateTime.DaysInMonth(currentDate.Year, currentDate.Month);
            ageInMonths = ageInMonths--;

            if (ageInMonths < 0)
            {
                ageInMonths += 12;
                ageInYears--;
            }
        }
        if (ageInMonths < 0)
        {
            ageInMonths += 12;
            ageInYears--;
        }

        Console.WriteLine("{0}, {1}, {2}", ageInYears, ageInMonths, ageInDays);
0
ответ дан 30 November 2019 в 04:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: